BeginAccept方法后无法关闭套接字

时间:2009-11-08 20:28:05

标签: c# networking sockets

我在c#中有一个程序,我在其中创建一个套接字,绑定它,开始监听然后使用beginaccept! 但是当我尝试关闭\ shutdown套接字时,我从beginaccept AsyncCallback方法获得异常!

     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);
            }
}
非常感谢!

3 个答案:

答案 0 :(得分:8)

当main_socket关闭时,将调用OnClientConnect(),但main_socket.EndAccept()应抛出ObjectDisposedException。也许您希望捕获该异常并将其视为“侦听器套接字已关闭”消息。

你的代码的另一个问题是main_socket实际上并没有连接到任何东西。在Disconnect_Click()中调用main_socket.Shutdown()可能也会抛出,但这次它应该是一个SocketException,说套接字没有连接。我会删除那个main_socket.Shutdown()调用。

答案 1 :(得分:1)

旧主题,但一个解决方案是:保留一个局部变量,以跟踪您何时"关闭/关闭"插座。我使用_isShutdown

当你开始收听套接字时,设置_isShutDown = False;
在关闭套接字之前,set _isShutdown = True;

EndAccept(iar)功能中,只能调用

 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..
}

答案 2 :(得分:0)

“要取消对BeginAccept方法的挂起调用,请关闭Socket。当异步操作正在进行时调用Close方法时,将调用提供给 BeginAccept 方法的回调。后续调用 EndAccept 方法将抛出 ObjectDisposedException 以指示操作已被取消。“

Socket.BeginAccept Method (AsyncCallback, Object)

正确的方法可能是:
1)在服务器上创建客户端套接字,连接到监听套接字,成功后EndAccept关闭它 2)MSDN建议的方式只是处理这个异常