I am using .Net\'s socket class and I am using the following code:
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);
This then
Timeout in case of Shutdown followed by Disconnect or BeginDisconnect will occur in the case if the other side Socket is not Receiving.
Here how it works: Shutdown(SocketShutdown.Send) (or Both) produce SENDING of zero byte to other side. And then if you call Disconnect it will block until other side accept this zero byte packet. This is why socket always receive zero byte during in Accept during graceful disconnection from Socket. Linger option and other settings have no effect on this 2 minute delay. You may check connection state with TCPView. So proper way is to make sure other side is either in Receive mode OR physically disconnected OR actually destroyed socket - for example application quit (you will get immediate exception in this case without 2 minute delay).
http://vadmyst.blogspot.ru/2008/04/proper-way-to-close-tcp-socket.html