在 .NET 核心中终止套接字接收
Terminate socket receive in .NET core
我正在 .NET 核心中编写一个 client/server 套接字库,这只是一个在另一个项目中使用的基本模型。
在客户端,我有三个线程,一个监听,一个发送,一个将收到的消息传回给消费者。
我正在尝试实现关闭客户端的关闭功能。发送和接收函数都是消费者,因此很容易告诉他们检查 ManualResetEvent。
但是,我能找到关闭接收线程的唯一方法是 运行 socket.Shutdown(),因为踏板卡在 socket.Recieve() 中。这会导致在侦听线程中抛出一个 SocketException,它可以被捕获、处理并彻底关闭。但是,当我无法确定 SocketException 的 NativeErrorCode 以了解它关闭的原因时,我的问题就出现了。
我不想通过捕获所有 SocketExceptions 来隐藏错误,只是捕获 NativeErrorCode 10004 错误。 NativeErrorCode 在 SocketException class 中不可访问,但我可以在 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)
//{
// }
}
}
代替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
}
}
我正在 .NET 核心中编写一个 client/server 套接字库,这只是一个在另一个项目中使用的基本模型。
在客户端,我有三个线程,一个监听,一个发送,一个将收到的消息传回给消费者。
我正在尝试实现关闭客户端的关闭功能。发送和接收函数都是消费者,因此很容易告诉他们检查 ManualResetEvent。
但是,我能找到关闭接收线程的唯一方法是 运行 socket.Shutdown(),因为踏板卡在 socket.Recieve() 中。这会导致在侦听线程中抛出一个 SocketException,它可以被捕获、处理并彻底关闭。但是,当我无法确定 SocketException 的 NativeErrorCode 以了解它关闭的原因时,我的问题就出现了。
我不想通过捕获所有 SocketExceptions 来隐藏错误,只是捕获 NativeErrorCode 10004 错误。 NativeErrorCode 在 SocketException class 中不可访问,但我可以在 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)
//{
// }
}
}
代替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
}
}