Socket.Shutdown throws SocketException

被刻印的时光 ゝ 提交于 2019-12-10 13:58:03

问题


I'm trying to implement async sockets for my project. Here's the code

    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);
        }
    }

but everytime I call Stop (which in turn, calls shutdown) (no matter clients are connected or not), Socket.Shutdown throws SocketException with message

Additional information: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

I'm really stuck here. Anyone knows what I'm doing wrong?


回答1:


Your listening socket is not connected. I think the message says this quite well. Everytime you accept a connection you get a new socket that is independent. The original socket is never connected to anything.

Just don't call Shutdown on it.

Btw, your Accept loop is using async IO, then waiting for it to complete. That makes no sense. Use the synchronous version.



来源:https://stackoverflow.com/questions/23963359/socket-shutdown-throws-socketexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!