2014-06-19 12 views
0

두 개의 프로그램 중 하나는 클라이언트이고 다른 하나는 클라이언트 용 서버입니다. 클라이언트는 같은 서버에 일부 데이터를 전송 한 후 응답을 읽Indy Server와 AdoQuery가 충돌합니다.

idtcpclient1.WriteLn(command); //Command contains data that the server needs eg. name and surname 
progressbar1.StepIt; 
sresult := idtcpclient1.ReadLn(); 

서버는 다음 라인을 읽고 정보를 조작하고 SQL 쿼리를 작성합니다.

adoquery1.Close; 
adoquery1.SQL.Text := 'select * from '+sGrade; 
adoquery1.Open; 

그러나 즉시 클라이언트에 오류가 제공하는 데이터베이스와의 연결을 열기로 "연결이 정상적으로 종료"

내가 입력을 시뮬레이션하여 클라이언트없이 서버 코드를 테스트하고 잘 작동

. 그렇지 않다면 왜 내가 다음 문제는 무엇인가 그것을

어떻게 고칠 수있는 경우

나는 인디과 AdoQuery이 충돌 생각이며 어떻게 해결해야합니까?

+0

Indy 사용시 서버와 통화하는 데 사용하고있는 포트는 무엇입니까? –

+2

문제는 Indy 서버 코드가 주 스레드 외부의 스레드에서 실행된다는 것입니다. indy 스레드 컨텍스트에서 연결/쿼리를 만들어야합니다. 또는 Synchronize를 사용하여 주 스레드의 컨텍스트에서 DB 코드를 실행합니다. – whosrdaddy

+0

포트를 사용하고 있습니다 : 55555 – Craig

답변

2

ADO는 아파트 스레드 COM 개체를 만드는 스레드에 선호도가있는 COM 개체를 사용합니다. 마샬링되어 있지 않으면 스레드 경계를 넘어서 사용할 수 없습니다.

인디의 TCP 서버는 멀티 스레드입니다. 각 클라이언트는 자체 스레드에서 실행됩니다.

스레드는 COM 개체와 액세스하기 전에 COM과의 관계를 설정하기 위해 CoInitialize/Ex()을 호출해야하며 COM을 사용하여 완료되면 CoUninitialize()을 호출해야합니다.

클라이언트의 연결을 끊는 캐치되지 않은 예외가 발생하기 때문에 서버가 실패합니다. COM을 초기화하지 않았기 때문에 가능성이 가장 높습니다.

클라이언트별로 ADO 개체를 만들어야하며 주 스레드에서 사용하지 마십시오. 서버의 OnConnect 이벤트에서 CoInitialize/Ex()으로 전화하십시오. OnDisconnect 이벤트에서 CoUninitialize()으로 전화하십시오. OnExecute 이벤트에서 필요에 따라 새 ADO 개체를 동적으로 만들고 사용하십시오.

이것은 각 클라이언트가 자체 데이터베이스 연결을 필요로한다는 것을 의미합니다. 필요하지 않으면 클라이언트가 필요할 때 요청을 게시 할 수있는 전용 스레드로 ADO 논리를 이동하십시오. 메인 쓰레드에서 데이터베이스 작업을하지 말고 거기에 속하지 않습니다.

0

데이터 모듈을 사용하는 경우 : 클라이언트 당 하나의 데이터 모듈 인스턴스를 만들어 스레드 오류를 피할 수 있습니다. Indy는 컨텍스트에서 클라이언트의 datamodule에 대한 참조를 보유 할 수 있습니다. 사용 가능한 리소스 및 트래픽에 따라 데이터 모듈 인스턴스 풀을 사용하십시오.

+0

어떻게 할 수 있습니까? – Craig