我正在使用.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)
//{
// }
}
}
答案 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
}
}