首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# TcpClient Socket.Send()接收大量数据,没有剩余字节

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

Stack Overflow用户
提问于 2015-01-09 02:38:28
回答 1查看 1.5K关注 0票数 0

我使用C# TcpClient发送一些数据包,它工作正常,但是Send()是一次接受2 2MByte的数据,所以我的上传进度计数器不能正常工作。

代码语言:javascript
运行
复制
  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)
                                            {


                                            }
                                        }

                                    }

我的调试输出如下所示,我已经验证了这个2mb数据包最终到达了另一端,尽管我的本地Tcp客户端声称它是立即以全部有效负载的返回值发送的。

代码语言:javascript
运行
复制
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%

因此,我的问题是如何实际地获得上传的真实进度的反馈,因为我知道它在后台占用时间,或者如何使C# Socket.Send()的行为更像Linux ()?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-09 02:58:50

你需要把寄件切成小块。你的代码

代码语言:javascript
运行
复制
int sendret = client.sock.Send(transmit_data, Transmit_offset, transmit_data.Length - Transmit_offset, SocketFlags.None);

会高兴地立刻发送一大块,这正是你不想要的。尝试一些类似于…的东西

代码语言:javascript
运行
复制
int sendsize = transmit_data.Length - Transmit_offset;
if (sendsize > 8860) sendsize = 8860;
int sendret = client.sock.Send(transmit_data, Transmit_offset, sendsize, SocketFlags.None);

当然,硬编码8860 (这是MTU 9000的最大有效载荷)是一个坏主意,使用常量!

编辑

要理解性能的含义,有必要理解

  • 当数据被放入最终发送缓冲区时,对的调用将返回,而不是在物理发送和确认时返回。
  • 与物理发送数据所需的时间相比,呼叫开销很小(慢速计算机上的10 is可能有不同的规则)。

这意味着,下一个Send()可能不会延迟任何事情:它将准备好下一个包,在前一个包上线之前,从而使线路保持全速。

这也意味着,您的进度计数器仍然稍微关闭:它将显示正在准备发送的数据包的进度,而不是那些正在发送和确认的数据包。在任何宽带连接上,人类都不太可能注意到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27853023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档