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
 
Thanks for the input.

I see this method is a .NET 2.0 addition. My program is in 1.1 for now (VS 2005 is actually on it's way to me as I type this) so I hadn't seen this option.

I suppose it's worthy to note that the .Shutdown method should be called before .Disconnect

I'll post back as soon as I get a chance to try it out.
 
Ok, your forum profile says you're using .Net 2.0. ShutDown normally goes before Close method also, if you don't set other Linger options, but Close should have cut off immediately when you didn't Shutdown. Alternative if you don't want remaining data in stream is to set DontLinger false and timeout 0 as described in documentation. Since the same socket then can't be reused to Connect again, you have to create a New Socket and connect this. It looks as your sub method does this, but you could have cut out a loop snippet trying to reconnect same socket instance. It doesn't sound as there are connection issues at the other end to me.
 
I had to leave this project for a while but now I"m back to it.

I tried socket.close in my Finally block, I've set the member variable to Nothing at the start of the routine that opens teh connection - all to no avail.

And I'm still noticing that when a connection to one device fails, I cannot make a connection to any other device.

My program goes out on the network and gathers some environmental data from a sensor device, uses that data to formulate a set of commands for the sign, then connects to the sign and sends the commands.

I've verified in the IDE that if the connection to the environmental sensor fails, the program on the next loop will not connect to the sign - an entirely different connection made in a different class altogether! I figure there's something ugly sitting on the thread my program is running under but I cannot figure out how to release it.

Can any one help me?

Other than this, the program works great!
 
OK, more data....

It appears that if you close ALL socket connections in the program, functionality is returned. I had the two sockets open in nested procedures. Closing the socket in the outer procedure did the trick.

Still lame, tho. A good .NET wrapper to WinAPI functions should work as expected, not just pass along the bad behavior of the underlying API. I'd think that the .NET library functions would use thread-safe methodologies so teh upper level code can "just work" like you want it to.
 
That sounds as it is a problem with the "other end". I have never encountered problems with opening new socket connections while others are still open. (edit: or one not closing when others are open..) I usually use the TcpClient/TcpListener wrappers but the socket close is done directly to the underlying socket (networksstream).
 
Last edited:
It is indeed a problem at the "other end" but I need to account for it in my code as I can't have the application just fail when there's a network disruption. This time the device is on the local LAN but that of course won't always be the case.

So the code opens a socket to the sign, then opens a socket to the environmental sensor device, reads the data, closes the connection to the env sensor, sends commands to the sign, and closes the sign connection. When the connection to the env sensor fails, I cannot make any further socket connections until the "sign" socket is also closed. Then I'm good to go.
 
You say you do this:

Create socket object
connect to env sensor
read data
disconnect from env sensor

...

You do kno whtat you cannot call COnnect again on this socket, right? It's gone, dead, disposed.. You need to make a new Socket object again to connect...
 
No, two different socket instances in two different classes.

Create socket #1 to sign
Create socket #2 to env sensor
read sensor via #2
close #2
send command to sign via #1
close #1

The problem was that if there was a timeout connecting socket #2, I could not use socket #1 (or any other intance of a socket) until #1 (i.e. all sockets) were closed.


I'm going to rework my sign object to queue up commands and then spit them out at once so that it wil be:

Open socket #1
read env sensor via #1
close #1

open socket #2
send all sign commands
close socket #2
 
mmh, but you didnt really answer my question?

I was trying to point out that after you have Close()d a particualr socket, you cannot open it again without destroying and recreating the instance. Your post only mentions that you open and close, it doesnt say what you do with the instances.. If i'm still not making myself clear, try this:

If you your code doesnt include the words "x = New Socket(host, port)" where x is the name of your socket variable, between a call to x.close and a subsequent call to x.connect, then the code will fail


Additionally, if the socket access is synchronous, i.e. blocking, and you are doing this in a single thread, then a call to read may hang the app until there is some data to read..
 
Yes, different socket instances in different classes. No overlapping of scope.

I was catching the exception, calling .close and anything else I could find that might do the trick.

The answer was to bubble the exception all the way out of the parent routine (object, method, whatever) and close that connection (to the sign). Then I could re-establish a new socket, connecting back up with the sign, calling the env sensor, etc.

I think the hang up is deeper in the Windows API - the same way that both MSXML *and* IE can only make two simultaneous connections (i.e. if you try to "Save Target As" from multiple links on a web page, you'll see that you can only have two actively downloading at once, the others will queue up). Maybe these behaviors have been changed in newer releases of both MSXML and IE, but it worked that way a couple years ago and that can't be an co-incidence, they must have been using the same lower-level code.
 
I think the hang up is deeper in the Windows API - the same way that both MSXML *and* IE can only make two simultaneous connections (i.e. if you try to "Save Target As" from multiple links on a web page, you'll see that you can only have two actively downloading at once, the others will queue up).


THis is a programmatic limit introduced by Microsoft. The actual limit is 4 connections active in IE - if you could only get 2 downloads going it means that another 2 browser windows were still trying to download the last bits of whatever page was on show. TweakUI could be used to raise this limit, as it is a registry setting.

It is completely unrelated to the low level behaviour of windows tcp/ip stack, which is capable of supporting thousands of simulataneous connections. A quick look at my system, given that Im currently downloading openoffice via bittorrent, shows that my machine is currently handling 894 concurrent, active socket conenctions.

When I said different instances, I was not talking about the env sensor being one, and the sign being another - im talking about the way you reconnect to both.. I'm nearly 100% sure there is a flaw in the logic you use for connecting to the remote end, or some design factor (like the env sensor wont accept more than 1 connection per 5 minutes) that has not been taken into account. I've never had a problem on any windows system, with apps that make hundreds/thousands of connections quickly (I wrote a proxy server for my uni dissertation, and used it for peer-2-peer file sharing just to hammer it. After a month, I had downloaded 200 gigs of data and made nearly half a million connections, without it falling over)
 
True, this is self-imposed client application limits following the recommendations from HTTP 1.0 and 1.1 protocol RFCs about concurrent connections to a single server. If you want to follow the HTTP standards you have to implement such limit for your client yourself, it is not part of the generic socket objects. The sockets may be also be used for different protocols on TCP/IP other than HTTP, you got a lot of other standard application protocols, DHCP, FTP, IRC, POP3, TELNET to name a few, have a look at Wiki for instance: http://en.wikipedia.org/wiki/Internet_protocol_suite
 
cjard,

The post following yours reminded me that it was a 2-connetion-per-host limit in IE that I was thinking of. But it was indeed a limit imposed in MSXML as well (which version, I don't recall, it's been a few years).

My connection methodology works well, the sign is normally updated every 2 seconds and is very reliable as long as there is no network disruption. And now that I'm bubbling up the connection closing to the outer loop, 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 didn't mean to imply that the Windows TCP/IP stack had the limitations. I used to be a senior dev at a major eCommerce .com and I also cross over to hardware/system design as well and I recall having thousands of active connections as a simple netstat would attest. I only meant that there was a limitation deeper than the .net socket components let me access.

Thanks for the input, though, you can never get enough of seeing things from different perspectives.
 
Back
Top