Hello,
I have a listener that returns a TcpClient that must read data until the other side closes or until we stop.
I have created a simple Form with two buttons. One starts one connection and the other stops it.
The problem is that when I have a IOException due to the timeout of the Read the socket is closed and I cannot communicate with it again. I cannot reconnect it as is the other side the one to establish the connection.
Just execute the code and telnet to the port 502, wait one second and you will see the problem.
How would you do that?
Public Class Form1
Private m_listener As Net.Sockets.TcpListener
Private m_client As Net.Sockets.TcpClient
Private m_stopping As Boolean
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim data As Byte()
Dim dataLength As Integer
ReDim data(512)
m_listener = New Net.Sockets.TcpListener(Net.IPAddress.Any, 502)
m_listener.Start()
m_client = m_listener.AcceptTcpClient()
m_client.GetStream().ReadTimeout = 1000
m_client.GetStream().WriteTimeout = 1000
While Not m_stopping
Try
dataLength = m_client.GetStream.Read(data, 0, data.Length)
If dataLength = 0 Then
MsgBox("Disconnected")
Else
MsgBox(dataLength.ToString() & " bytes received")
End If
Catch ex As Exception When TypeOf (ex) Is TimeoutException OrElse (Not ex.InnerException Is Nothing AndAlso TypeOf (ex.InnerException) Is Net.Sockets.SocketException AndAlso DirectCast(ex.InnerException, Net.Sockets.SocketException).ErrorCode = 10060)
''# Just retry
End Try
End While
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
m_stopping = True
End Sub
End Class
This question is related to the question: http://stackoverflow.com/questions/1973956/how-to-close-a-tcpclient-when-the-other-end-has-been-closed-in-net
FINALLY: The real problem is that to know when a client has closed the connection I must do a Read and check for a return of 0. If the Read has infinite Timeout the call will block and I will not be able to end the application until the Read returns something, if the read has a finite Timeout I can have a TimeoutException and then the Socket will be closed. So ... HOW THE HELL I'M SUPPOSED TO KNOW WHEN THE OTHER PART HAS CLOSED THE CONNETION? I can not believe that something so "easy" is so hard.