question

kirillandy-0856 avatar image
0 Votes"
kirillandy-0856 asked kirillandy-0856 commented

Winsock 2 - what error to expect from accept()

Hello! I have a small question regarding the behavior of the accept() function in Winsock2. It's a bit of an awkward one, which I could probably figure out myself, but I can't get my networking equipment to cooperate and reproduce the test case :D. I was hoping someone had to handle this possible error at some point and could let me know what to expect (or not expect if this a wild goose chase).

The question is simple: so suppose I have an AF_INET TCP server socket bound to an address and listening. I make a blocking accept() call and wait for connections. What would happen in case of an event that makes the blocking socket... um... "invalid"? Like a disconnect from the network, or a change in IP address?

I suspect that there should be a scenario where accept() returns with an error, because a socket tied to, say, a Wi-Fi interface W in network MyNetwork, with a dynamic IP address of N.N.N.10, let's say, simply CAN'T accept anything after we disconnect from the network, or, for whatever earthly reason, get re-assigned address N.N.N.(not 10)?

I did do some basic checking.

1) Manually disconnecting from a network while you've got a blocking socket gives... nothing. The socket keeps blocking and, moreover, re-connecting to the network and attempting to receive stuff actually continues to work! So simple disconnects don't do anything.

2) I tried to force my PC's IP address available in my router settings (there's a big button with "Force available" written on it :D), but the blocking socket still received stuff. Not sure if this is indicative of anything, since the DHCP lease time probably still needs to run out after the "force available", I haven't got any documentation that details how the feature works...

3) I tried disconnecting and connecting back after the "force available". Same thing, connections can still come through. I am assigned the same old IP address, so it doesn't seem any different to scenario (1)

I could just disable my Wi-Fi interface while I'm at it, at this point, see if that results in anything :D

The question is: what has to happen for a blocking server socket to return with an error that says "mate, you're not in the network any more, there's nothing for me to expect"?
And what error would I get? The main ones I would expect would be WSAEINVAL and WSANETDOWN...

windows-api
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

XiaopoYang-MSFT avatar image
0 Votes"
XiaopoYang-MSFT answered kirillandy-0856 commented

According to WSAAccept,

When issuing a blocking Winsock call such as WSAAccept, Winsock may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation,.......

Perhaps what you need is Receiving Connection Notifications.

· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I'm not quite sure what you mean... Yes, I did see the note about APCs, and I don't yet understand what I can do with the connection notifications you have suggested...

To clarify, I am NOT using WSAAccept(), I'm using accept(), in case that matters.

The issue I have is: what sort of situation would force a perfectly well set-up and blocking TCP server socket to return an error? How dire must the circumstances be for the socket to be rendered "unusable"? Because so far, most of my attempts have not been able to trigger anything.

  • Disconnecting from the network does not make accept() return.

  • Forcing my PC IP address available (whatever that implies) does not make accept() return.

And I can live with that, seeing how the server will still be able to receive connections after I re-connect to the network.
I cannot say this with regards to a change in IP address, I haven't been able to make that happen, yet, but after some thought, I think I know how I can force it to change.

Disabling the Wi-Fi interface entirely is yet to be checked but it is not a common use case so I'm not worried about it. I will run the test nonetheless.

So are there any other situations besides the ones I have listed which may make accept() return? What error would I need to catch exactly?
I need this in order to know when I should start monitoring my network connection (via the Wlan API callback, let's say) in order to figure out when it's OK to re-start the TCP server.

0 Votes 0 ·

All return values are documented.
I'm afraid the requirement is not the accept's duty which just waits for connections that will come in the queue.

1 Vote 1 ·

Oh, OK, that's straightforward. So in other words, the created and bound server will just keep on waiting regardless of what happens because it's not its responsibility to even check whether it CAN possibly accept anything (apart from the errors that are documented, typical preliminary check-ups for Winsock initialization, a bind() call, etc...).

(As a side note, I have checked what happens if you shut down the Wi-Fi interface during a blocking accept() call: nothing. The call keeps blocking. You'd think you'd get a WSAENETDOWN at the very least, but you don't, which is OK :D)

So then the question is: how would I forcibly make accept() return? Say I want to shut down my application and clean up all resources. The server is running on a separate thread. To close the thread, I'd preferably want to exit the accept() call and return. So how would I force the accept() call to unblock? Would a simple WSACleanup() call do the trick?
Or is this exactly why I should use non-blocking calls? What's the neater approach here?

0 Votes 0 ·
Show more comments