Alex
Alex

Reputation: 2531

How to close Winsock UDP socket hard?

I need to close UDP socket which has unsent data immediately. There is SO_LINGER parameter for TCP sockets but I didn't find out anything for UDP. It's on Windows.

Thanks in advance.

Update 0:

I give background of this question. I have application 1st thread opens/binds/closes socket, 2nd thread sends datagrams to it. In some cases after closing the socket (errorcode = 0) bind function returns errorcode 10048 "Address already in use". I found out after close() execution port is still used (via netstat command). Maybe I ask incorrect question and the reason of such behavior is something else?

Upvotes: 1

Views: 3793

Answers (3)

Winter Dragoness
Winter Dragoness

Reputation: 1325

I was having this problem with a windows UDP socket as well. After hours of trying everything I finally found my problem was that I was calling socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) on the main thread to create the socket, calling bind(...) and recvfrom() on a worker thread, then after closing the worker thread I called closesocket(...) on the main thread. None of the functions returned an error but tor some reason, doing this leaves the UDP address/port combination in use (so a future call to bind() triggers error 10048 WSAEADDRINUSE and netstat -abot -p UDP also shows the port still in use until the whole application is closed). The solution was to move socket(...) and closesocket(...) calls into the worker thread.

Other than weird issues like the case above, there is normally no way that a UDP server socket can be left open after calling closesocket() on it. Microsoft explains that there is no connection maintained with a UDP socket and no need to call shutdown() or any other function. Usually the reason a TCP socket is left open after calling closesocket() is that it wasn't disconnected gracefully and it's waiting for about 4 minutes in TCP_WAIT state for possible additional data to come in before it actually closes. In the case above, netstat showed the UDP socket never closed until the application was closed even if I waited 30+ minutes.

If you're using a wrapper around winsock like the .NET framework, I've also read some features like setting up async callbacks can leave a UDP socket bound open if you don't clean up the callbacks correctly, but I don't think there are any such features in the win32 winsock API that can cause that.

Upvotes: 1

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84199

For all application purposes once your send() returns, the packet is "sent". There's no send-buffer like in TCP, and you have no control over the NIC packet queue. Normal close() is all you need.

Edit 0:

@EJP, here's a quote from UNP for you (Section 2.11 "UDP Output"):

This time, we show the socket send buffer as a dashed box bacause it doesn't really exist. A UDP socket has a send buffer size (which we can change with the SO_SNDBUF socket option, Section 7.5), but this is simply an upper limit on the maximum-sized UDP datagram that can be written to the socket. If an application writes a datagram larget than the socket send buffer size, EMSGSIZE is returned. Since UDP is unreliable, it does not need tp keep a copy of the application's data and does not need an actual send buffer. (The application data is normally copied into a kernel buffer of some form as it passes down the protocol stack, but this copy is discarded by the datalink layer after the data is transmitted.)

This is what I meant in my answer - you have no control over the send buffer - , so "for all application purposes" it does not exist.

Upvotes: 1

user207421
user207421

Reputation: 311018

Just close it. There's nothing in UDP that says that pending data will be sent, unlike TCP.

Upvotes: 0

Related Questions