2016-11-10 26 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 
     } 
    }