在.NET核心中终止套接字

时间:2016-11-10 04:11:09

标签: c# sockets asp.net-core .net-core

我正在使用.NET核心编写客户端/服务器套接字库,这只是在另一个项目中使用的基本模型。

在客户端,我有三个线程,一个是监听,一个是发送,另一个是将收到的消息传递给消费者。

我正在尝试实现关闭功能以关闭客户端。发送和接收功能都是消费者,因此很容易告诉他们检查ManualResetEvent。

但是,我能找到关闭接收线程的唯一方法是运行socket.Shutdown(),因为胎面卡在socket.Recieve()中。这会导致在侦听线程中抛出SocketException,可以捕获,处理和干净地关闭它。但是,当我无法确定SocketException的NativeErrorCode以了解它为何关闭时,我的问题就出现了。

我不希望通过捕获所有SocketExceptions来隐藏错误,只是NativeErrorCode 10004错误。 NativeErrorCode在SocketException类中是不可访问的,但我可以在IntelliSense中看到它,有什么想法吗?

 private void ListenThread()
    {
        //Listens for a recieved packet, first thing reads the 'int' 4 bytes at the start describing length
        //Then reads in that length and deserialises a message out of it
        try
        {
            byte[] lengthBuffer = new byte[4];
            while (socket.Receive(lengthBuffer, 4, SocketFlags.None) == 4)
            {
                int msgLength = BitConverter.ToInt32(lengthBuffer, 0);
                if (msgLength > 0)
                {
                    byte[] messageBuffer = new byte[msgLength];
                    socket.Receive(messageBuffer);
                    messageBuffer = Prereturn(messageBuffer);
                    Message msg = DeserialiseMessage(messageBuffer);
                    receivedQueue.Enqueue(msg);
                    receivedEvent.Set();
                    MessagesRecievedCount += 1;
                }
            }
        }
        catch (SocketException se)
        {
            //Need to detect when it's a good reason, and bad, NativeErrorCode does not exist in se
            //if(se.NativeErrorCode == 10004)
            //{

           // }
        }
    }

1 个答案:

答案 0 :(得分:1)

而不是se.NativeErrorCode你可以使用se.SocketErrorCode(System.Net.Sockets.SocketError),它更清楚。

另外,我通常使用异步套接字。它们建立在事件模型上,所以如果有东西到达套接字缓冲区,则会调用回调函数

    public void ReceiveAsync()
    {
       socket.BeginReceive(tempBytes, 0, tempBytes.Length, 0, ReadCallback, this);//immediately returns 
    }

    private void ReadCallback(IAsyncResult ar)//is called if something is received in the buffer as well as if other side closed connection - in this case countBytesRead will be 0
    {
       int countBytesRead = handler.EndReceive(ar);
       if (countBytesRead > 0)
       {
           //read tempBytes buffer
       }
    }