C# Socket.Shutdown抛出SocketException

C# Socket.Shutdown抛出SocketException,c#,sockets,serversocket,asyncsocket,C#,Sockets,Serversocket,Asyncsocket,我正在尝试为我的项目实现异步套接字。这是密码 public void Start(int listeningPort) { var ipHostInfo = Dns.Resolve(Dns.GetHostName()); var ipAddress = ipHostInfo.AddressList[0]; var localEndPoint = new IPEndPoint(ipAddress, listeningPort);

我正在尝试为我的项目实现异步套接字。这是密码

    public void Start(int listeningPort)
    {
        var ipHostInfo = Dns.Resolve(Dns.GetHostName());
        var ipAddress = ipHostInfo.AddressList[0];
        var localEndPoint = new IPEndPoint(ipAddress, listeningPort);

        _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _listener.Bind(localEndPoint);
        _listener.Listen(3000);
        Started = true;

        Task.Factory.StartNew(() =>
        {
            while (Started)
            {
                allDone.Reset();

                _listener.BeginAccept(AcceptCallback, _listener);

                allDone.WaitOne();
            }
        });
    }

    public void Stop()
    {
        Started = false;
        _listener.Shutdown(SocketShutdown.Both); //<-- throws SocketException
        _listener.Close(2000);
        _listener = null;
    }

    public void Kick(IClient client)
    {
        try
        {
            Clients.Remove(client);
            client.Socket.Shutdown(SocketShutdown.Both);
            client.Socket.Close();
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

    private void AcceptCallback(IAsyncResult ar)
    {
        Socket handler = null;
        try
        {
            allDone.Set();

            var listener = (Socket) ar.AsyncState;
            handler = listener.EndAccept(ar);

            var client = new Client(this, handler);
            Clients.Add(client);

            var state = new StateObject();
            state.Socket = handler;
            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            var client = ClientBySocket(handler);
            if(handler != null && client != null) Kick(client);
        }
    }

    private void ReadCallback(IAsyncResult ar)
    {
        Socket handler = null;
        try
        {
            var state = (StateObject) ar.AsyncState;
            handler = state.Socket;

            var bytesRead = handler.EndReceive(ar);
            if (bytesRead > 0)
            {
                if (Received != null)
                {
                    var buff = new byte[bytesRead];
                    if (buff[0] == 0)
                    {
                        Stop();
                    }
                    return;
                    Array.Copy(state.Buffer, buff, bytesRead);
                    Debug.WriteLine(Encoding.UTF8.GetString(buff));
                    try
                    {
                        Received(this, new ReceiveArgs(buff));
                    }
                    catch(Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                    }
                }
            }
            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            var client = ClientBySocket(handler);
            if (handler != null && client != null) Kick(client);
        }
    }
public void启动(int-listingport)
{
var ipHostInfo=Dns.Resolve(Dns.GetHostName());
var ipAddress=ipHostInfo.AddressList[0];
var localEndPoint=新的IPEndPoint(ipAddress,listeningPort);
_侦听器=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
_Bind(localEndPoint);
_听,听(3000);
开始=真;
Task.Factory.StartNew(()=>
{
while(启动)
{
全部完成。重置();
_beginacept(AcceptCallback,_listener);
全部完成。WaitOne();
}
});
}
公共停车场()
{
开始=错误;
_listener.Shutdown(SocketShutdown.Both);//0)
{
如果(已接收!=null)
{
var buff=新字节[bytesRead];
if(buff[0]==0)
{
停止();
}
返回;
复制(state.Buffer、buff、bytesRead);
Debug.WriteLine(Encoding.UTF8.GetString(buff));
尝试
{
接收(此,新接收参数(buff));
}
捕获(例外情况除外)
{
Debug.WriteLine(例如消息);
}
}
}
BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReadCallback,state);
}
捕获(例外情况除外)
{
Debug.WriteLine(例如消息);
var client=ClientBySocket(处理程序);
如果(handler!=null&&client!=null)踢(client);
}
}
但每次我调用Stop(这反过来又调用shutdown)(无论客户端是否连接),Socket.shutdown都会抛出带有消息的SocketException

其他信息:发送或接收数据的请求被取消 不允许,因为套接字未连接并且(在通过 数据报套接字(使用sendto调用)未提供地址


我真的被困在这里了。有人知道我做错了什么吗?

您的监听插座未连接。我认为这条信息很好地说明了这一点。每次您接受一个连接时,都会得到一个独立的新套接字。原始插座从未连接到任何东西

只要别叫关机就行了


顺便说一句,您的Accept循环正在使用异步IO,然后等待它完成。这毫无意义。使用同步版本。

1。但我应该如何停止服务器套接字?我是否应该单独关闭每个套接字(侦听器除外)?2.关于异步IO。如果我在EndAccept之后调用BeginAccept会更好吗?那样的话,我就不需要手动重置事件了,对吗。只需关闭侦听器。它独立于所有其他插座。在未连接的插座上关机应该打开什么?!没有要发送或接收的数据。2.您可以选择:不等待的异步IO或同步IO。混合很少有意义。我建议尽可能使用同步IO,因为它更容易编程和调试。如果你不得不问,你可能应该去同步。