gpt4 book ai didi

c# - Socket.EndReceive(...) 没有正确返回

转载 作者:行者123 更新时间:2023-11-30 15:36:14 27 4
gpt4 key购买 nike

我正在尝试使用 Socket.BeginReceive(...) 和 Socket.EndReceive(...) 作为我的 UDP 数据包接收器客户端。它按预期接收和处理数据包,但是,当我希望取消和关闭套接字时,我实现的 Close() 函数在 Socket.EndReceive(...) 上退出。我假设在线程上抛出了一个异常,但我无法弄清楚如何捕获异常以查看问题所在。我之前使用过 Socket.EndReceive(...),SocketError 返回成功。下面是一些代码,展示了我如何使用套接字。

更新代码

void _startReceiving()
{
_buffer = new byte[Marshal.SizeOf(typeof(EthernetShare.Message))];
_receiveResult = _udpSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, messageProcessor, null);
}

private void messageProcessor(IAsyncResult result)
{
int packetSize = _udpSocket.EndReceive(result);
if (packetSize == _buffer.Length)
{
byte[] packet = _buffer;
IAsyncResult asyncResult = result;
_startReceiving();
OnMessageReceieved(_buffer.ToStruct<DataStreamingMessage>());
}
}
public void Stop()
{

_continue = false;
SocketError error;
try
{
int tmp = _udpSocket.EndReceive(_receiveResult, out error);

}
catch (Exception)
{

throw;
}
_udpSocket.Close();
}

旧代码

private Socket _udpSocket;
private byte[] _buffer;
private IAsyncResult _receiveResult;
void _startReceiving()
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(EthernetShare.Message))];
_receiveResult = _udpSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, messageProcessor, null);
//_receiveResult = _udpSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, messageProcessor, _continue);
}

private void messageProcessor(IAsyncResult result)
{

//if ((bool)result.AsyncState && result.IsCompleted)
if (result.IsCompleted)
{
_buffer = new byte[Marshal.SizeOf(typeof (EthernetShare.Message))];
//_receiveResult = _udpSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, messageProcessor, _continue);
_receiveResult = _udpSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, messageProcessor, null);
}
}


public void Stop()
{

_continue = false;
SocketError error;
try
{
int tmp = _udpSocket.EndReceive(_receiveResult, out error);

}
catch (Exception)
{

throw;
}
_udpSocket.Close();
}

最佳答案

您对 APM(异步编程模型)的使用是错误的。请参阅:http://msdn.microsoft.com/en-us/library/ms228963.aspx

对 BeginXXX 的每次调用都应与 EndXXX 匹配。

在伪代码中,它可能看起来像这样:

private bool isClosed;
private Socket socket;

void BeginReceiveNextPacket(){
socket.BeginReceive(..., EndReceiveNextPacket);
}

void EndReceiveNextPacket(IAsyncResult result){
try{
// By making a call to EndReceive, we allow the socket to wrap up, close internal handles and raise any exceptions if they exist.
socket.EndReceive(result);

// Now make a new call to BeginReceive after we invoked the actual call to EndReceive.
BeginReceiveNextPacket();
}
catch(SocketClosedException) {
if (closed){
// We forcefully closed this socket. Therefore, this exception was expected and we can ignore it.
}
else{
throw; // Catch an unexpected exception.
}
}
}

void Stop(){
isClosed = true;
socekt.Close();
}

关于c# - Socket.EndReceive(...) 没有正确返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13908836/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com