using sockets with an LED message sign

Namlak

Member
Joined
Jan 2, 2007
Messages
9
Programming Experience
10+
I'm writing a VB.NET app that sends commands to an LED message sign periodically. It runs as a service. I'm using the .NET Socket library and things are working perfectly!

Until there is a network disruption, that is.

I'm catching and bubbling up any exceptions and that's working fine, too. The problem is that once the Socket object's .connect method fails with an exception, it will *never* make another connection - timing out after 10 seconds with another exception. This object has only Sub scope (Dim'd in the Sub, connection opened, data sent, connectiton closed).
So here's the testing routine:

1) Start App, watch sign update itself every few seconds, great.

2) Pull network plug on sign

3) Watch the .connect method throw an exception

4) Step through program in IDE, watch exceptions faithfully bubble up to the main loop

5) Next loop, watch the .connect method fail again, exceptions bubble up, no problem

6) Plug Network wire back in

7) Watch .connect method fail on each subsequent loop. Exceptions work as expected.

Here's what's weird - if I go over and reset the power on the sign, subsequent connections work perfectly. Note that I'm power-cycling the sign while the IDE is in interactive debug mode - I'm not restarting the app. In fact, if I plug the network back in and re-start the app, it works again, too - without resetting the sign.

So there's obviously *something* hanging on to this connection/socket and I have a feeling it's something deeper within the Windows networking system.

The question is - how do I get it to "let go" programmatically? I've tried all sorts of variations on Socket = Nothing, Socket.close, etc and nothing seems to work.

Here is some relevent code:
VB.NET:
Public Sub DoSomeStuff()
  Dim Socket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
  Try
    Dim RemoteEP As New System.Net.IPEndPoint(_IPAddress, 5005)
    Socket.Connect(RemoteEP)
    If Not Socket.Connected Then Throw New Exception("Could not Connect to Sign:" & _IPAddress.ToString & "-" & _HostName)
 
    --- Send "Sign Language" :^) ---
 
    Socket.close()
  Catch ex As Exception
    Throw New Exception("Could not Connect to Sign:" & _IPAddress.ToString & "-" & _HostName)
  End Try
End Sub
 
I only have to endure the 10-second-or so connection timeout before the updates resume. I also understand that there is nothing that can be done to circumvent this timeout limitation.
I don't know exactly what timeout you ask about here, but I think you perhaps mean the synchronous socket.connect method. For socket connection operation you can specify the thread timeout for an asynchronous BeginConnect call. The return value is a IAsyncResult object which contain reference to the threads waithandle, the AsyncWaitHandle property. Here you can call WaitOne overload with timeout. Example:
VB.NET:
Sub startconnect()
    Dim tcp As New Net.Sockets.TcpClient
    Dim ar As IAsyncResult = tcp.BeginConnect("address", 1234, AddressOf connect, tcp)
    If ar.AsyncWaitHandle.WaitOne(5000, False) Then
        'connected
    Else
        'timeout
    End If
End Sub
 
Sub connect(ByVal ar As IAsyncResult)
    DirectCast(ar.AsyncState, Net.Sockets.TcpClient).EndConnect(ar)
End Sub
 
I'm using the synchronous method. I don't have the time to reference it now but I've read that there is no adjustment for that timeout.

I've read about asynch methodologies but haven't really gotten around to wrapping my head around it. I'm on a tight schedule of projects so usually the straight-ahead technique gets the nod. Thanks for the example, though. When work and kids allow me the time to investigate, I'll do so.
 
Back
Top