2016-11-10 31 views
0

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

在客户端,我有三个线程,一个听,一个发送,并且其中一个传递接收讯息传回给消费者。

我正试图实现关闭功能来关闭客户端。发送和接收函数都是消费者,所以他们很容易就告诉检查ManualResetEvent。

不过,我能找到关闭接收线程的唯一方法是运行socket.Shutdown()由于胎面卡在socket.Recieve()。这会导致在监听线程中抛出SocketException,可以捕获,处理和完全关闭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

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

另外,我通常使用异步套接字。它们都建在事件模型,所以如果事情到达а套接字缓冲区,回调FUNC将被称为

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