I’m using an idTCPServer for processing data.
For a new device I need to hand over the socket to a dll (stop the tcp server to read from that socket).
Is that possible with Indy or ICS?
[Edit]
For test purposes I made a thread instead of using the dll, because the lack of hardware.
procedure TfrmIndyMain.IdTCPServer1Connect(AContext: TIdContext);
begin
FMyThread := TMyThread.Create(true);
FMyThread.FSocket := AContext.Binding.Handle;
FMyThread.Resume;
end;
procedure TfrmTest.IdTCPServer1Execute(AContext: TIdContext);
begin
// Its necessary that indy stop reading from the socket, without reset a lot of messages is lost
AContext.Binding.Reset(false); //not sure if this is correct
end;
procedure TMyThread.Execute;
var
len: integer;
data: string;
begin
ioctlsocket(FSocket, FIONREAD, len);
if len>0 then
begin
Setlength(data, len);
if recv(FSocket, pointer(data)^, len, 0) <> SOCKET_ERROR then
Log('Data: ' + data)
else
Log('Error');
end;
end;
In Indy, you can use the
TIdPeerThread.Connection.Binding.Socketproperty (Indy 9 and earlier) or theTIdContext.Connection.Socket.Binding.Handleproperty (Indy 10 – shortcut asTIdContext.Binding.Handle) to access the underlyingSOCKEThandle.Update: Indy maintains an
InputBufferof data that is read from the socket during Indy-based reading operations. That includes calls toTIdTCPConnection.Connected(), whichTIdTCPServercalls in between successive triggers of theOnExecuteevent. So it is possible that you do not see all of the data that is on the socket because you are not looking at theInputBufferfor cached data. To avoid that, you would have to make sure the event only triggers once by running your own reading loop inside the event and avoid calling any of Indy’s reading methods, eg:If possible, a better solution would be to change your logic to not need to access the socket directly anymore. Let Indy do all of the reading normally, and then pass any received data to the rest of your code for processing, eg: