简体   繁体   English

C#TcpClient Socket.Send()接受大量数据,没有剩余字节

[英]C# TcpClient Socket.Send() accepting very large amounts of data, no left over bytes

I am using C# TcpClient in the following way to send a few packets,it is working correctly, but Send() is accepting 2MByte of data in one shot, so my upload progress counter is not working correctly.. 我正在以以下方式使用C#TcpClient发送一些数据包,它工作正常,但是Send()在一枪中接受2MByte的数据,因此我的上传进度计数器无法正常工作。

  Console.WriteLine("New transmit pack len={0}", transmit_data.Length);

                                    while ((Transmit_offset < transmit_data.Length) && (client.sock.Poll(0, SelectMode.SelectWrite)))
                                    {
                                        int sendret = client.sock.Send(transmit_data, Transmit_offset, transmit_data.Length - Transmit_offset, SocketFlags.None);
//#if SocketDebug
                                           Console.WriteLine("Sent " + sendret + " bytes");
//#endif
                                        Transmit_offset += sendret;
                                        BytesOut += sendret;


                                        if (transmit_data.Length > 512)
                                        {
                                            double progress = ((double)Transmit_offset / (double)transmit_data.Length) * 100;
                                            Console.WriteLine("Upload offset=" + offset + " packetlen="+PacketLen + " progress="+progress);
                                            //Console.WriteLine("Data transfer complete!");

                                            UploadProgress = Convert.ToInt32(progress);
                                           // Console.WriteLine("Up={0}", UploadProgress);
                                            if (progress > 100)
                                            {


                                            }
                                        }

                                    }

My Debug output is the following, and i have verified that this 2mb packet eventually arrives at the other end, despite my local Tcp Client claiming that it was sent immediately with the return value of the full payload.. 我的Debug输出如下,尽管我的本地Tcp客户端声称它是随有效载荷的返回值立即发送的,但我已经验证了此2mb数据包最终到达另一端。

SendBufferSize=8192
New transmit pack len=47
Sent 47 bytes
Connected
Sending file Server v1.56.exe....
New transmit pack len=79
Sent 79 bytes
New transmit pack len=2222367
Sent 2222367 bytes
Upload offset=0 packetlen=11504 progress=100
Upload Progress: 100%
Upload Progress: 100%
Upload Progress: 100%
Upload Progress: 100%

So my question is how to realistically get feedback of the real progress of the upload because i know its taking its time in the background, or how do i make C# Socket.Send() behave more like Linux send()? 因此,我的问题是如何实际获取上传实际进度的反馈,因为我知道它在后台花了很多时间,或者如何使C#Socket.Send()的行为更像Linux send()?

You need to cut the send into smaller pieces. 您需要将发送切成小块。 Your code 您的密码

int sendret = client.sock.Send(transmit_data, Transmit_offset, transmit_data.Length - Transmit_offset, SocketFlags.None);

will happily send a big chunk at once, which is exactly what you don't want. 会一次愉快地发送一大块,这正是您不想要的。 Try something along the lines of 尝试一些类似的方法

int sendsize = transmit_data.Length - Transmit_offset;
if (sendsize > 8860) sendsize = 8860;
int sendret = client.sock.Send(transmit_data, Transmit_offset, sendsize, SocketFlags.None);

Ofcourse hardcoding 8860 (which is max payload for MTU 9000) is a bad idea, use a constant! 当然,硬编码8860(对于MTU 9000是最大有效负载)是个坏主意,请使用常量!

EDIT 编辑

To understand the performance implications it is necessary to understand, that 要了解性能影响,有必要了解

  • the call to Send() will return, when data is put in the final send buffer , not when it is physically sent and acknowledged 当将数据放入最终的发送缓冲区中时 ,而不是在物理上发送并确认后,对Send()的调用将返回
  • the call overhead is tiny compared to the time it takes to physically send the data (10GE on a slow machine might have different rules) 与物理发送数据所花费的时间相比,呼叫开销很小(慢速计算机上的10GE可能具有不同的规则)

This means, that the next Send() is likely not to delay things at all: It will have prepared the next packet, before the previous one is on the wire, thus keeping the line at full speed. 这意味着,下一个Send()可能根本不会延迟任何事情:它将在下一个数据包在线之前准备好下一个数据包,从而使该行保持全速。

This also implies, that your progress counter is still slightly off: It will show the progress of the packets being ready to send, not those being sent and acknowledged. 这也意味着您的进度计数器仍然略有偏离:它将显示准备发送的数据包的进度,而不是正在发送和确认的数据包的进度。 On any broadband connection this is very unlikely to be noticable to a human being. 在任何宽带连接上,人类都不太可能注意到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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