简体   繁体   中英

C# Begin Send within a foreach loop issue

I have a group of "Packets" which are custom classed that are coverted to byte[] and then sent to the client. When a client joins, they are updated with the previous "Catch Up Packets" that were sent previous to the user joining. Think of it as a chat room where you are updated with the previous conversations.

My issue is on the client end, we do not receive all the information; Sometimes not at all..

Below is pseudo c# code for what I see

code looks like this.

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);
     }
}

Is this some sort of throttle issue or an issue with sending to many times: ie: if there are 4 packets in the queue then it calls begin send 4 times.

I have searched for a topic similiar and I cannot find one. Thank you for your help.

Edit: I would also like to point out that the sending between clients continues normally for any sends after the client connects. But for some reason the packets within this for loop are not all sent.

I would suspect that you are flooding the TCP port with packets, and probably overflowing its send buffer, at which point it will probably return errors rather than sending the data.

The idea of Async I/O is not to allow you to send an infinite amount of data packets simultaneously, but to allow your foreground thread to continue processing while a linear sequence of one or more I/O operations occurs in the background.

As the TCP stream is a serial stream, try respecting that and send each packet in turn. That is, after BeginSend, use the Async callback to detect when the Send has completed before you send again. You are effectively doing this by adding a Sleep, but this is not a very good solution (you will either be sending packets more slowly than possible, or you may not sleep for long enough and packets will be lost again)

Or, if you don't need the I/O to run in the background, use your simple foreach loop, but use a synchronous rather than Async send.

Okay,

Apparently a fix, so far still has me confused, is to Thread.Sleep for the number of ms for each packet I am sending.

So...

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);
} 

I assume that for some reason the loop stops some of the calls from happening... Well I will continue to work with this and try to find the real answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM