C#在foreach循环问题中开始发送

C#在foreach循环问题中开始发送,c#,sockets,foreach,C#,Sockets,Foreach,我有一组自定义分类的“数据包”,它们被转换成字节[],然后发送到客户端。当客户机加入时,它们将使用之前发送给加入用户的“追赶数据包”进行更新。把它想象成一个聊天室,在那里你可以通过以前的对话得到更新 我的问题是在客户端,我们没有收到所有的信息;有时一点也不 下面是我看到的伪c代码 代码看起来像这样 lock(CatchUpQueue.SyncRoot) { foreach(Packet packet in CatchUpQueue) { // If I

我有一组自定义分类的“数据包”,它们被转换成字节[],然后发送到客户端。当客户机加入时,它们将使用之前发送给加入用户的“追赶数据包”进行更新。把它想象成一个聊天室,在那里你可以通过以前的对话得到更新

我的问题是在客户端,我们没有收到所有的信息;有时一点也不

下面是我看到的伪c代码

代码看起来像这样

lock(CatchUpQueue.SyncRoot)
{
     foreach(Packet packet in CatchUpQueue)
     {
           // If I put Console.WriteLine("I am Sending Packets"); It will work fine up to (2) client sockets else if fails again.
          clientSocket.BeginSend(data, 0, data.length, SocketFlags.None, new AsyncCallback(EndSend), data);
     }
}
这是某种节流问题还是发送多次的问题:即:如果队列中有4个数据包,那么它会调用begin send 4次

我已经找了一个类似的主题,但我找不到。谢谢你的帮助

编辑:我还想指出,在客户端连接之后,客户端之间的发送通常会继续进行。但是由于某些原因,这个for循环中的数据包并没有全部发送。

好的

显然,到目前为止,我仍然困惑不解的一个解决办法是线程。为我发送的每个数据包的毫秒数休眠

所以

for(int i=0;i

我假设由于某种原因,循环会阻止某些调用的发生。。。好的,我将继续研究这个问题,并试图找到真正的答案。

我怀疑您正在用数据包淹没TCP端口,并可能溢出其发送缓冲区,在这一点上,它可能会返回错误,而不是发送数据

异步I/O的思想不是允许您同时发送无限量的数据包,而是允许您的前台线程在后台发生一个或多个I/O操作的线性序列时继续处理

由于TCP流是一个串行流,请尝试遵守该规则并依次发送每个数据包。也就是说,在BeginSend之后,在再次发送之前,使用异步回调来检测发送何时完成。通过添加睡眠,您可以有效地做到这一点,但这不是一个很好的解决方案(您可能发送数据包的速度比可能的慢,或者您可能睡眠时间不够长,数据包将再次丢失)


或者,如果您不需要在后台运行I/O,请使用简单的foreach循环,但使用同步发送而不是异步发送。

创建套接字时,您是使用UDP还是TCP作为协议类型?UDP没有传递保证,可能会丢失。您的回调方法是否检查任何错误?您可能需要在其中设置断点以查看通信结果的状态。我猜您需要等待第一个
BeginSend
完成,然后才能调用下一个调用
BeginSend
。尝试将
BeginSend
替换为
Send
,以查看您的问题是否消失。如果是这样,您知道需要等待异步操作首先完成。协议是TCP。回调函数检查长度前缀,除非正确,否则不会返回数据包。发送无法解决此问题。该服务器充当授权服务器。客户端连接到它并发送到它。服务器将消息重新广播给特定的客户端。服务器将数据包存储到队列中,然后当新客户端加入时,它会将该队列重新发送给客户端。这就是我的问题所在。所有其他发送方法都按预期工作。套接字是否处于非阻塞模式?如果Socket.Blocking=false,您需要自己进行缓冲。有人能解释一下为什么在begin send创建异步线程来执行时需要休眠线程吗?您的回答完美地描述了我的情况。这就解决了我的问题,谢谢。@Devon:你应该点击空心复选框来接受这个答案。
for(int i = 0; i < PacketQueue.Count; i++)
{
     Packet packet = PacketQueue[i];
     clientSocket.BeginSend(data, 0, data.length, SocketFlags.None, new AsyncCallback(EndSend), data);
     Thread.Sleep(PacketQueue.Count);
}