为什么 BeginReceive() 不是 return 多次读取?
Why does BeginReceive() not return for more than one read?
在下面的代码中,我从 Main()
调用 Receive()
,后者又调用 Async BeginReceive()
,并在后台线程中完成接收数据。
问题:对于第一次读取,BeginReceive 成功并附加了 StringBuilder。然而,当再次调用时,if(bytesread>0)
条件永远不会达到,因此我永远不会对收到的数据采取行动。
我希望 BeginReceive 处理不止一次读取,并且(我认为这与线程有关)我希望 Main()
函数始终监听来自客户端的新命令(不是新连接,我'我想保留相同的套接字)。这可能吗?
解决方案的尝试:我添加了 ManualResetEvent 以试图阻止 Main()
函数在另一个线程中进行异步读取之前退出。
Main()中的相关代码:
Receive(server); //await instructions from the client
done.WaitOne(); //This is a ManualResetEvent.
Console.ReadLine();
方法定义:
public static void Receive(Socket server)
{
try
{
SocketArgs sockargs = new SocketArgs();
sockargs.handler = server;
server.BeginReceive(sockargs.buffer, 0, sockargs.buffersize, 0, new AsyncCallback(ReceiveCallBack), sockargs);
}
catch
{
}
}
public static void ReceiveCallBack(IAsyncResult ia)
{
try
{
SocketArgs sockargs = (SocketArgs)ia.AsyncState;
Socket server = sockargs.handler;
int BytesRead = server.EndReceive(ia);
if (BytesRead > 0)
{
//Continue reading data.
sockargs.sb.Append(Encoding.ASCII.GetString(sockargs.buffer, 0, BytesRead));
MessageBox.Show(sockargs.sb.ToString());
server.BeginReceive(sockargs.buffer, 0, sockargs.buffersize, 0, new AsyncCallback(ReceiveCallBack), sockargs);
}
else
{ //Do stuff with sb.ToString()
done.Set();
}
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}
BytesRead only returns 套接字断开连接时为零。因此,我的问题的解决方案是简单地处理 else{} 部分中的断开连接。
更多信息可以绑定在这很有帮助article。
编辑:为了澄清,我在 if() 构造的末尾留下了 BeginReceive() 调用,因此 "always" 发生了 BeginReceive() 操作。
重置事件以便WaitOne
再次阻塞。根据评论,事件错误地处于设置状态,导致 Main 退出。
在下面的代码中,我从 Main()
调用 Receive()
,后者又调用 Async BeginReceive()
,并在后台线程中完成接收数据。
问题:对于第一次读取,BeginReceive 成功并附加了 StringBuilder。然而,当再次调用时,if(bytesread>0)
条件永远不会达到,因此我永远不会对收到的数据采取行动。
我希望 BeginReceive 处理不止一次读取,并且(我认为这与线程有关)我希望 Main()
函数始终监听来自客户端的新命令(不是新连接,我'我想保留相同的套接字)。这可能吗?
解决方案的尝试:我添加了 ManualResetEvent 以试图阻止 Main()
函数在另一个线程中进行异步读取之前退出。
Main()中的相关代码:
Receive(server); //await instructions from the client
done.WaitOne(); //This is a ManualResetEvent.
Console.ReadLine();
方法定义:
public static void Receive(Socket server)
{
try
{
SocketArgs sockargs = new SocketArgs();
sockargs.handler = server;
server.BeginReceive(sockargs.buffer, 0, sockargs.buffersize, 0, new AsyncCallback(ReceiveCallBack), sockargs);
}
catch
{
}
}
public static void ReceiveCallBack(IAsyncResult ia)
{
try
{
SocketArgs sockargs = (SocketArgs)ia.AsyncState;
Socket server = sockargs.handler;
int BytesRead = server.EndReceive(ia);
if (BytesRead > 0)
{
//Continue reading data.
sockargs.sb.Append(Encoding.ASCII.GetString(sockargs.buffer, 0, BytesRead));
MessageBox.Show(sockargs.sb.ToString());
server.BeginReceive(sockargs.buffer, 0, sockargs.buffersize, 0, new AsyncCallback(ReceiveCallBack), sockargs);
}
else
{ //Do stuff with sb.ToString()
done.Set();
}
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}
BytesRead only returns 套接字断开连接时为零。因此,我的问题的解决方案是简单地处理 else{} 部分中的断开连接。
更多信息可以绑定在这很有帮助article。
编辑:为了澄清,我在 if() 构造的末尾留下了 BeginReceive() 调用,因此 "always" 发生了 BeginReceive() 操作。
重置事件以便WaitOne
再次阻塞。根据评论,事件错误地处于设置状态,导致 Main 退出。