1

Is there any way for my TCP/IP listener to detect if there are currently conencted client?

This is my code:

Public Sub StopListen()
    client.Close()
    tcpClientThread.Abort()
    server.Stop()
    SyncLock accessLock
        endThread = True
    End SyncLock
    Btn_Listen.Text = "Listen"
End Sub

The problem in that code is whenever the user pressed the Stop Listen button and there are currently no cients connected to my listener an error occurs.

How can I do something like this?

Public Sub StopListen()
   If thereIsConnectedClient Then
       client.Close()
   End If

   tcpClientThread.Abort()
   server.Stop()
   SyncLock accessLock
      endThread = True
   End SyncLock
   Btn_Listen.Text = "Listen"
End Sub
Cary Bondoc
  • 2,923
  • 4
  • 37
  • 60

1 Answers1

0

Generally speaking, after the SYNC-SYNC,ACK-ACK three way handshake, the connection is established and TcpListener returns a tcpClient. This tcpClient can be kept in an array. The number of elements in this array represents the number of connections.

In the normal scenario, after server and client exchange data packets, either the server or the client will initiate a FIN request. After the FIN-ACK,FIN-ACK flags are exchanged, connection finished and that tcpClient can be removed from the array.

Now if there are clients not actively closing the socket, then the server may need an mechanism to disconnect the inactive socket. Either by having a timeout on the connection. Or periodically send some empty packet and wait for the ACK from the remote client to decide whether the client is still present.

Peter Peng
  • 1,910
  • 1
  • 27
  • 37
  • Nobody needs to "have a timeout" on sockets, these are implicitly set and cannot be removed, not even with low-level API. BUT one can adjust the timeout to large values so it effectively will timeout long after the application stopped running ... which is a bad thing and noone should even think about that. As for "empty packets" : totally useless, TCP has an inbuilt KEEPALIVE mechanism and AFAIR its enabled by default ... sockets will get destroyed and/or throw exceptions if either side times out or disconnects. – specializt Aug 13 '15 at 07:13
  • @specializt A server wouldn't want to keep inactive unclosed socket alive forever. TcpClient has the SendTimeout and ReceiveTimeout which can be used to determine if remote side unreachable. How a server handle the connections is really depends on how data exchange protocol is defined. Anyway, if a client disconnect itself without properly close the underlying socket, service side will not be aware of that until actively send something. Check out this post: http://stackoverflow.com/questions/722240/instantly-detect-client-disconnection-from-server-socket – Peter Peng Aug 13 '15 at 08:22
  • thats entirely wrong, sorry. As long as TCP KEEPALIVE is activated the server will be "notified" of connection problems once the next bunch of KEEPALIVE packet times the threshold fails. If your specific implementation disables KEEPALIVE you're on your own and need to detect these things manually ... which is a beginners' mistake. This is how its done for .NET : `socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);`, apparently. Its pretty sad that KEEPALIVE is not enabled by default in .NET but that doesnt change the facts – specializt Aug 13 '15 at 08:24
  • @specializt the TCP implementation isn't useful for most application level requirements. You can't send one on demand, and for most operating systems the TCP keepalive timeout is only configurable on a system-wide level and set far too high to be generally useful for applications. – Peter Peng Aug 13 '15 at 08:47
  • @specializt The reason for an keep-alive on application level is that the TCP standard recommends to set the keep-alive timer to higher than two hours. Never seen an TCP connection without traffic that survives this time. Hence the TCP keep-alive stuff is useless by default. See http://stackoverflow.com/questions/1480236/does-a-tcp-socket-connection-have-a-keep-alive – Peter Peng Aug 13 '15 at 08:53
  • yet again : totally and utterly wrong. Please stop making things up, there is no "system wide level" as all of these settings are bound to APPLICATION SCOPE (assembly scope). You can set the socket timeouts on send/receive individually : http://howtostartprogramming.com/vb-net/, you can set the TCP keepalive interval and timeout : https://msdn.microsoft.com/en-us/library/system.net.servicepoint.settcpkeepalive(v=vs.110).aspx and whatnot. I recommend reading a good book about basic programming and maybe even .NET basics. – specializt Aug 13 '15 at 09:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86869/discussion-between-peter-peng-and-specializt). – Peter Peng Aug 13 '15 at 09:49