Cannot Close Socket After BeginAccept Method
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);
}
开发者_StackOverflow社区 catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
many thanks!
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
socket.EndAccept() when _isShutdown is false
<pre><code>
if (_isShutdown == false)
{
someWorkSocket = listenSocket.EndAccept(iaSyncResult);
//...
}
else
{
//socket is closed, and we shouldn't use it. Should erase this else clause..
}
"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
After beginaccept is thread in connEventStatus.WaitOne(); state. You must unblock thread by connEventStatus.Set(); . It cause that thread will be continue. Now you must end socket by YourSocket.Close(). For the last I dispose thread in which I run it. But be carefull that while loop can not create new beginaccept imediately you unblock thread by connEventStatus.Set(); :-) .
Thats all
精彩评论