Connect()
을 호출 할 때마다 새 연결을 만들고 TIdTCPServer
은 새 풀을 시작하여 해당 연결을 처리합니다 (스레드 풀링을 사용 가능하게 설정하지 않은 경우). 그게 네가 정말로 원하는거야? 클라이언트가 일정 기간 동안 연결을 열린 상태로두고 가능한 한 많이 기존 연결을 다시 사용하는 것이 더 효율적입니다. 잠시 동안 유휴 상태 일 때와 같이 실제로는 더 이상 필요하지 않을 때만 연결을 끊습니다. 새 연결을 설정하는 것은 양 끝 모두에서 비용이 많이 드는 작업이므로 최대한 오버 헤드를 줄여야합니다. 클라이언트 측에
, 당신은 Write(data)
를 호출 할 때, 그것은 전체 TIdBytes
보낼 것이다, 그러나 당신은 많은 바이트를 기대할 어떻게 과학적 이해 있도록 서버에 그 TIdBytes
의 길이를 전송하지 않습니다. TIdIOHandler.Write(TIdBytes)
당신을 위해 그렇게하지 않으면 수동으로해야합니다.
서버 측에서는 ReadBytes()
에 한 번에 4 바이트 만 읽도록 지시하고 있습니다. 각 블록의 4 바이트 후, OnExecute
이벤트 핸들러를 종료하고 다음 블록의 4 바이트를 읽기 위해 다시 호출되기를 기다리고 있습니다. 클라이언트 소스의 길이가 TIdBytes
인 경우가 4의 짝수 배가 아닌 한 ReadBytes()
은 클라이언트의 마지막 블록을 4 바이트 미만으로 읽으려고하면 서버 연결이 끊어 지므로 예외가 발생하므로 서버 코드가 그 블록을받지 못한다.
대신을 시도해보십시오
그와
procedure SendData(var data: TIdBytes) ;
begin
FormMain.IdTCPClient.Connect;
try
FormMain.IdTCPClient.IOHandler.Write(Longint(Length(data)));
FormMain.IdTCPClient.IOHandler.Write(data);
finally
FormMain.IdTCPClient.Disconnect;
end;
end;
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
data: TIdBytes;
begin
with AContext.Connection.IOHandler do
ReadBytes(data, ReadLongint, false);
// process data
end;
말했다 클라이언트 코드를 변경하면 TIdBytes
길이가 어떤 이유에서 옵션을 선택하지 않습니다 보낼 수 있다면, 대신이 서버 코드를 사용
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
LBytes: Integer;
data: TIdBytes;
begin
// read until disconnected. returns -1 on timeout, 0 on disconnect
repeat until AContext.Connection.IOHandler.ReadFromSource(False, 250, False) = 0;
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(data);
// process data
end;
을
또는 :
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
strm: TMemoryStream;
data: TIdBytes;
begin
strm := TMemoryStream.Create;
try
// read until disconnected
AContext.Connection.IOHandler.ReadStream(strm, -1, True);
strm.Position := 0;
ReadTIdBytesFromStream(strm, data, strm.Size);
finally
strm.Free;
end;
// process data
end;
또는 :
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
strm: TMemoryStream;
begin
strm := TMemoryStream.Create;
try
// read until disconnected
AContext.Connection.IOHandler.ReadStream(strm, -1, True);
// process strm.Memory up to strm.Size bytes
finally
strm.Free;
end;
end;
답장을 보내 주셔서 감사합니다. 패키지를 하나의 큰 패키지로 병합했습니다. 스트림으로 읽었고 이제는 작동합니다. 감사! – hunyadym