I have a code in Visual Basic, that have a timer and listening a tcpip stream. I´m try to code it in deplhi, but I have problems.
I get connect sucessful in board with tcpip like this : IdTCPClient1.Connect;
Board tcpip is 192.168.0.180, port 2000, my server is 192.168.0.30.
I´m try this code :
procedure TForm1.Button8Click(Sender: TObject);
var StrStream: TMemoryStream;
begin
if IdTCPClient1.Connected then
begin
StrStream := TMemoryStream.Create;
if IdTCPClient1.IOHandler.Connected then
IdTCPClient1.IOHandler.ReadStream(StrStream,-1,false);
Memo1.Lines.Add('hello');
end;
end;
The problem is, in line IdTCPClient1.IOHandler.ReadStream(StrStream,-1,false); the application stop, no error, no message and I don´t undestand.
VB code
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Try
If tcp1.Available > 1 Then
Dim leitura As NetworkStream = tcp1.GetStream
Dim bytes(tcp1.ReceiveBufferSize) As Byte
leitura.Read(bytes, 0, CInt(tcp1.ReceiveBufferSize))
returndata = Encoding.ASCII.GetString(bytes)
txtSerial1.AppendText(returndata)
End If
If tcp2.Available > 1 Then
Dim leitura As NetworkStream = tcp2.GetStream
Dim bytes(tcp2.ReceiveBufferSize) As Byte
leitura.Read(bytes, 0, CInt(tcp2.ReceiveBufferSize))
returndata = Encoding.ASCII.GetString(bytes)
txtSerial2.AppendText(returndata)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
When calling the IOHandler's ReadStream()
method, setting AByteCount=-1
and AReadUntilDisconnect=False
as you are tells ReadStream()
to expect the incoming data to be preceded by a multi-byte integer (either 4 or 8 bytes, depending on the IOHandler's LargeStream
property) that specifies the number of subsequent bytes in the data, and it then waits for that many bytes to actually arrive. Is that what the server's data actually looks like? I doubt it, because that is not what your VB code is expecting.
Using the IOHandler's ReadBytes()
method with AByteCount=-1
would be a closer equivalent to your VB code than using the ReadStream()
method, eg:
procedure TForm1.Button8Click(Sender: TObject);
var
Bytes: TIdBytes;
begin
if IdTCPClient1.Connected then
begin
IdTCPClient1.IOHandler.ReadBytes(Bytes, -1);
// use Bytes as needed...
Memo1.Lines.Add('hello');
end;
end;
Also, keep in mind that Indy uses blocking socket I/O by default. You really shouldn't perform blocking operations in the main UI thread. You should move your reading logic to a separate worker thread instead. Or, at the very least, make sure you set a small ReadTimeout
on the TIdTCPClient
so ReadBytes()
does not block the UI for very long.