2
votes

For almost a week I am reading and trying to find a solution for checking connection state using a TCP Client (using socket class) In my scenario I have a TCP Client that is connected to a server (it is not controlled by me) and i want that from time to time to check the connection state, and reconnect if necessary. I have read a lot of information on the internet but i did not find a suitable solution.

Briefly, these are the methods that i have found on the internet and try to implement. But unfortunatelly, i have found some scenarios where the TCP Server is closed and the TCP Client is still saying Connected

May i kindly ask someone that have encountered this issue to help me?

1.Example from MSDN

Private Function IsConnected(tcpSocket As Socket) As Boolean
    Dim blockingState As Boolean = tcpSocket.Blocking
    IsConnected = False
    Try
        Dim tmp(0) As Byte
        tcpSocket.Blocking = False
        tcpSocket.Send(tmp, 0, 0)
        Return True
    Catch e As SocketException
        If e.NativeErrorCode.Equals(10035) Then
            Return True
        Else : Return False
        End If
        ThrowError(e)
    Finally
        tcpSocket.Blocking = blockingState
    End Try
End Function

2.Example using Poll

Function Connected() As Boolean
    Connected = False
    If (tcpSocket.Connected) Then
        If ((tcpSocket.Poll(0, SelectMode.SelectWrite)) AndAlso (Not tcpSocket.Poll(0, SelectMode.SelectError))) Then
            Dim b As Byte() = New Byte(1) {}
            If tcpSocket.Receive(b, SocketFlags.Peek) = 0 Then
                Return False
            Else : Return True
            End If
        Else
            Return False
        End If
    Else
        Return False

    End If
End Function

3.Using Poll

Private Function Connect2() As Boolean
        Connect2 = False
        If tcpSocket.Poll(0, SelectMode.SelectRead) = True Then
            Dim byteArray As Byte() = New Byte(1) {}
            If (tcpSocket.Receive(byteArray, SocketFlags.Peek)) = 0 Then Connect2 = True
        End If
        Return Connect2()
End Function
2
There is by principle no reliable way to know if the connection is still usable without receiving a value from the remote side. The network in between might just be a black hole and you'd never know without receiving something.usr

2 Answers

0
votes

Systems often handle this kind of problem by implementing a 'heartbeat' mechanism where the client periodically sends a 'are you alive' request to the server. Is there any cheap, non-destructive request you can send to the server periodically that would allow you to ensure the socket is actually alive?

0
votes

This was something I struggled with for quite some time and never really found a catch-all solution. Unfortunately there is not a 100% reliable way, which is why most system implement a 'heartbeat' (as Steve Townsend mentioned).

The closest I could get was something like this (translated from C# by memory):

Public Function IsConnected() as Boolean
    Try
        Return tcpSocket <> Nothing AndAlso Not(tcpSocket.Poll(-1, SelectMode.SelectRead) _
                 AndAlso tcpSocket.Available = 0)
    Catch (ObjectDisposedException)
        Return False
    End Try
End Function

I don't know your setup exactly, but you mention you are connecting to a scale. Perhaps you could try reading the weight from it periodically as a form of 'heartbeat'.