tags:

views:

791

answers:

2

Hey.

I call Bind() and then Listen() on a System.Net.Sockets.Socket. None of these calls throw an exception.

Later, I make a call to:

Socket.Select(myreadlist,mywritelist,myerrorlist,0);

with myreadlist and myerrorlist containing the socket in question. Select reports my socket as having had an error, by leaving the socket in errorList, instead of removing it from the list. Nowhere in the program a SocketException is thrown.

I can't seem to figure out the correct way I should be asking the system: "okay, so what went wrong?"

Does anybody know?

Thanks, Lucas

edit: add 4th argument=0 for select + explained better how select() tells me an error has occured.

A: 

I don't know C# but I do know UNIX sockets. My first thought was that you hadn't called accept() on the socket before selecting for read but (and this is proof I know less about sockets than I thought) you can select in the listen state to see which sockets can be accepted. Oh well, we live and learn, even at my advanced age :-)

Anyhow, referring to the MSDN docs here, found through Google with ("c#" socket bind listen select), it states:

If you receive a SocketException, use SocketException.ErrorCode to obtain the specific error code. Once you have obtained this code, you can refer to the Windows Socket Version 2 API error code documentation in MSDN for a detailed description of the error.

These error codes appear to be documented here, found with a Google search on (Windows Socket Version 2 API error code documentation in MSDN).

I'm mentioning the Google search terms in case MSDN move their pages around. I'd output the error code from the exception caught, then look it up in the list on that second link to get the actual reason for failure. Once we know that, we may be able to help you further (or it might become blindingly obvious to the point you don't need to ask us again :-).

One thing that seems incongruous: the prototype for the call has a fourth argument, number of microseconds to wait if no activity. Your code in the question doesn't have that. Now, as I said, I know little about C# so it may default to something (or maybe you've just left it off the question by accident).

But I would watch for a known bug if you're using -1 (or it defaults to -1): see here for details but it basically means -1 returns immediately rather than waiting forever. Workaround is to use -2 to give you an hour or so but you'll still have to cater for the fact it may return even though there's been no activity.

If it's not throwing an exception, but simply setting the error indication in myerrorlist, that's a hairier problem. I can see nothing is the docs that show how to easily figure it out but I'd look at these possibilities.

  • You may be able to call the WSA functions (e.g., WSAGetLastError()) to figure it out. I'm not sure how easy this is from C#. You could try to accept() the errant socket and see if that gives you an exception detailing why it's a problem.
  • The Socket class has a Handle member which is the operating system handle for the socket. It may be possible to extract error information by following that.
  • Have you thought about using threads for connection processing and bypassing the use of select() altogether (i.e., using only accept() but from multiple threads)?

Another thing I found has to do with socket debugging. This page has a section at the bottom which shows how to do network tracing. .NET 2 apparently didn't support this for select() but that may have changed in the latest version.

paxdiablo
Thanks for your answer. Unfortunately a SocketException is never thrown. Select() signals an error by keeping the socket in myerrorlist, instead of removing it.I'll edit the question to account for the missing 4th argument. I use 0 in my code.
Lucas Meijer
A: 

The documentation for the Select() call says this:

If you have made a non-blocking call to Connect, the checkerror parameter identifies sockets that have not connected successfully.

And the documentation for the Poll() method (which it suggests using to determine the status of a single socket) in the SelectError mode says:

true if processing a Connect that does not block, and the connection has failed; -or- true if OutOfBandInline is not set and out-of-band data is available; otherwise, returns false.

Based on this, I'd say these are the only two conditions in which a socket indicates an error status without having previously thrown an exception. You didn't mention calling Connect(), but if you do, I would verify it's actually making the connection. Out-of-band data is pretty rare, but maybe your other end socket is doing something weird.

mbyrne215
You don't call connect() from the server side, that's a client-side call. The Q'er has called bind() and listen() and is using select() to detect which sockets they can accept().
paxdiablo
You're right, I wasn't thinking about that part so closely. But the point remains that there seems to be only a few conditions that will make the error status true without throwing an exception. It might just be that using the errorList isn't appropriate for this socket.
mbyrne215