1

So i know there are a lot of articles out there on this topic and i did read a lot of them i would say but for some reason im sure my code is not doing what it is supposed to do.

I want to close a connection between my Server and my Client. Now on the serverside i start the disconnect with this code

public void shutdown() { _socket.Shutdown(SocketShutdown.Both); _socket.Close(); } 

And on the Client side i have some troubles understanding how i get to the disconnect what i believe is happening is the following: in my async receive callback i should get an error since the server started a shutdown sequence and i have to handle that (right???) so my code for the client looks like this: ReceiveCallback:

private void ReceiveCallback(IAsyncResult result) { int bytesRecieved = 0; byte[] tempBuff; //Try to receive But if a Socket error occures disconnect otherwise start Receiving again try { bytesRecieved = _socket.EndReceive(result); } catch (SocketException sockEx) { Disconnect(sockEx); return; } catch (ObjectDisposedException disposeEx) { Disconnect(disposeEx); return; } catch (Exception ex) { StartReceive(); return; } if (bytesRecieved == 0) { StartReceive(); return; } tempBuff = new byte[bytesRecieved]; Buffer.BlockCopy(_buffer, 0, tempBuff, 0, bytesRecieved); StartReceive(); _packHandler.handlePacket(tempBuff); } 

Disconnect:

public void Disconnect() { if (!_socket.Connected) { return; } _socket.BeginDisconnect(false, DisconnectCallback, null); } 

DisconnectCallback

private void DisconnectCallback(IAsyncResult result) { _socket.EndDisconnect(result); _socket.Close(); } 

(The Disconnect Method is overloaded so if i get an exception it puts up a messageBox and then also calls Disconnect. Just so i know what happened.)

Where am i wrong and what can i improve uppon ???

I tried the code and it seemed to work but i then looked with netstat if all sockets are closed and the client socket was not. It was in FIN_WAIT_2 which means that it (or the server???) did not yet send the FIN packet right ? Oh and then i tried it again with this line changed:

if (bytesRecieved == 0) { StartReceive(); return; } 

TO

if (bytesRecieved == 0) { Disconnect; return; } 

which then threw an exception on the serverside and on the clientside the client said that the connection was closed by the server ???

EDIT: Even when i have closed both Programs Netstat still shows the port in a WAITING status. what does that tell me ?

2 Answers 2

1

Your normal disconnect has a shutdown which will clear the socket so it can disconnect properly but your async style never calls shutdown. I added it in a convenient location below.

public void Disconnect() { if (!_socket.Connected) { return; } _socket.Shutdown(SocketShutdown.Both); // Make sure to do this _socket.BeginDisconnect(false, DisconnectCallback, null); } 

EDIT:

From the sounds of it you don't have a reason to be using the Async Method? The async methods are so you can send data in a separate execution thread freeing up your thread to do some data processing for instance while that occurs.

I don't see any processing going on so I suggest you change disconnect like this and see if it resolves the problem. Because I don't think you are waiting on the Async methods which will not work out well.

public void Disconnect() { if (!_socket.Connected) { return; } shutdown(); //Your standard disconnect that you showed up top. Scoping might be required. } 

A bit of data on Async can be scrounged up here: http://msdn.microsoft.com/en-us/library/38dxf7kt(v=vs.110).aspx

Sign up to request clarification or add additional context in comments.

11 Comments

Ok thanks for the reply. Could you explain what exctly happens when i call shutdown and then what happens with the beginDisconnect and what is the difference between sync sockets and async sockets for this disconnect ?
UPDATE: I tried it but the socket is still open. EDIT : Now my server also crashes with an exception saying the client closed the connection already the moment i stop my server
I think you are using the Async methods mixed in a bad way and not waiting on them. Anyway I edited and explained some above.
Ok i guess you are right i dont want to do any processing anymore so i change that back to sync i still have that one open socket in FIN_WAITING_2 though it goes to WAITING if i close the client application EDIT: but i also get a exception if i add a line _socket.Close() after the shutdown in the client and in that moment my server crashes but if you look with netstat it says that the connection status is CONNECTED ????
You have a _socket.Close() inside of your shutdown function so calling it again would give an exception.
|
1

Important is:

  • If a server starts a shutdown sequence you DO have to handle it
  • Both sides have to call shutdown on their socket
  • You need a way to notice the disconnect (it does not give you an error, or least it didnt for me)

Therefor I created my own class customSocket which inherits from Socket

public class customSocket : Socket { #region Properties private readonly Timer _timer; private const int _interval = 1000; private bool Connected { get { bool part1 = Poll(1000, SelectMode.SelectRead); bool part2 = (Available == 0); if (part1 && part2) return false; else return true; } } public bool EventsEnabled { set { if (value) { _timer.Start(); } else _timer.Stop(); } } #endregion #region Constructors public customSocket(AddressFamily addressFamily, SocketType sockType, ProtocolType protocolType) : base(addressFamily, sockType, protocolType) { _timer = new Timer { Interval = _interval }; _timer.Elapsed += TimerTick; } public customSocket(SocketInformation sockInfo) : base(sockInfo) { _timer = new Timer { Interval = _interval }; _timer.Elapsed += TimerTick; } #endregion #region Events public event EventHandler<EventArgs> Socket_disconected; public void Raise_Socket_disconnected() { EventHandler<EventArgs> handler = Socket_disconected; if (handler != null) { handler(this,new EventArgs()); } } private void TimerTick(object sender, EventArgs e) { if (!Connected) { Raise_Socket_disconnected(); } } #endregion } 

This version of a socket has an Event for a disconnect. Now if you create an instance of your socket class you have to connect the handler and set the EventsEnabled true.

This handler then calls the shutdown and your socket does not stay in FIN_WAIT_2

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.