오늘은 Delphi 2010과 함께 제공되는 Indy 10을 사용하여 이상한 행동에 직면했습니다. 여기에 문제는 다음과 같습니다클라이언트가 Indy에서 서버에 연결할 때 IOHandler.ReadStream이 스레드를 차단하는 이유는 무엇입니까?
한다고 가정 우리는 우리의 클라이언트의 IdTcpClient, 우리의 서버 응용 프로그램에서 IdTcpServer, 우리 IdTcpServer에 대한의 OnExecute 이벤트 핸들러에서이 코드를 가지고 : 이제
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
AStream: TStringStream;
S: string;
begin
AStream := TStringStream.Create;
try
AContext.Connection.IOHandler.ReadStream(AStream);
S := AStream.DataString;
finally
AStream.Free;
end;
end;
, 클라이언트를 TIdTcpClient.Connect를 사용하여 서버에 연결하려고 시도합니다. 서버에서 TIdTcpServer.OnExecute가 호출되고 실행이 AContext.Connection.IOHandler.ReadStream (AStream) 줄에 도달하면 OnExecute 이벤트 처리기 내에서 실행되는 스레드가 차단됩니다.
코드를 추적 할 때 ReadLongInt가 ReadStream 내부에서 호출되어 바이트 수를 계산할 때 문제가 발생합니다. ReadLongInt는 ReadBytes를 호출합니다. ReadBytes 안에는 FInputBuffer.Size가 0입니다. 루프에서 ReadFromSource가 호출되고 결국 WinSock2에서 "select"함수를 호출하는 TIdSocketListWindows.FDSelect에 실행이 도달하고 여기서 실행이 중지되고 해당 클라이언트 연결에서 아무 것도 수신되지 않습니다. AByteCount 및 AReadUntilDisconnect 매개 변수에 값을 부여하려고 시도했지만 동작을 변경하지 않았습니다.
ReadStream을 ReadLn으로 바꾸면 서버에 연결해도 코드 실행이 차단되지 않고 클라이언트에서 보낸 데이터가 서버에 의해 읽혀집니다.
코드에 문제가 있습니까? 아니면이 버그입니까?
감사
설명해 주셔서 감사합니다. Indy 문서에서 AByteCount가 -1이고 AReadUntilDisconnect가 False이면 바이트 수는 IOHandler에서 정수로 읽히지 만 수신 된 데이터의 처음 4 또는 8 바이트에서 읽히지는 몰랐습니다. AReadUntilDisconnect가 False이고 AByteCount가 -1 일 때 ReadStream은 입력 버퍼에 무언가가있는 한 읽습니다. 어쨌든, 도와 주셔서 다시 한번 감사드립니다. – vcldeveloper
IOHandler의 모든 읽기 방법은 InputBuffer에서만 데이터를 가져옵니다. 다른 메서드가 내부적으로 호출하는 ReadBytes() 메서드는 InputBuffer에 각 읽기 작업에 사용할 수있는 충분한 바이트가 있는지 확인합니다. InputBuffer에 이미 4 바이트가 있으면 ReadStream()은 그대로 4 바이트를받습니다. InputBuffer가 아직 4 바이트를 가지지 않는다면, ReadBytes()는 그것을 확인하고, 이후 ReadStream()은 InputBuffer로부터 그것을받습니다. 어느 쪽이든, 모든 데이터는 소켓에서 InputBuffer로 이동하여 필요에 따라 각 읽기 메소드로 이동합니다. –