I have a program in c# in which i create a socket, binding it, begin listening and then using beginaccept! but then when I try to close\shutdown the socket I get exceptions from the beginaccept AsyncCallback method!
private void start_listening()
{
main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150);
main_socket.Bind(iplocal);
main_socket.Listen(5);
main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
private void Disconnect_Click(object sender, EventArgs e)
{
main_socket.Shutdown(SocketShutdown.Both);
main_socket.Close();
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this);
clients[connected_clients].Socket = main_socket.EndAccept(asyn);
clients[connected_clients].WaitForData();
main_socket.BeginAccept(OnClientConnect, null);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
many thanks!
"To cancel a pending call to the BeginAccept method, close the Socket. When the Close method is called while an asynchronous operation is in progress, the callback provided to the BeginAccept method is called. A subsequent call to the EndAccept method will throw an ObjectDisposedException to indicate that the operation has been cancelled."
Socket.BeginAccept Method (AsyncCallback, Object)
proper way could be :
1) create client socket at server, connect to listening socket, after successful EndAccept close it
2) the way suggested by MSDN is just to handle this exception as is
When main_socket is closed, OnClientConnect() will be called but main_socket.EndAccept() is supposed to throw an ObjectDisposedException. Perhaps you want to catch that exception and treat it as a "The listener socket has been closed" message.
The other problem with your code is that main_socket is not actually connected to anything. Calling main_socket.Shutdown() in Disconnect_Click() might throw too, but this time it should be a SocketException saying that the socket is not connected. I would remove that main_socket.Shutdown() call.
Old topic, but one solution is: Keep a local variable, to keep track of when you "close/shutdown" the socket. I use
_isShutdown
.When you start listening on the socket, set _isShutDown = False;
Before you close the socket,
set _isShutdown = True;
In the
EndAccept(iar)
function, only call