C#深刻理解TCP通信(总有你懂的)

牧草177 2013-10-10 10:10:55
使用C#和TCP已经可以传输数据甚至文件了,但是对于如何提高传输性能,一直感到很困惑(不是计算机网络通信相关专业的)。提出来,请大家一直帮助讨论一下!

TCP传输有两个策略,一个是发送端的Nagle算法,一个是ACK延迟反馈机制。网上虽然有很多资料,但都将讲的不深,所以我对这两个理解也就有了问题。

1、发送端在发送数据时,c#默认是启用Nagle算法的,说是要等到数据包达到一定大小或超过一定时间才会发送出去。
a.请问一下,这个数据包大小到底是多大?这个超时时间是多长呢?
b.再一个,在有些数据采集系统中,可能采集的数据才几十字节,比如30个字节。用TCP协议传送,额外好像需要多出44个字节。那如果在没超时的情况下,数据采集系统采集了10次,用Nagel算法组合的数据包长度时应该44+30*10,还是(44+30)*10呢?
c.如果取消Nagle算法,应该就是有数据就直接发出去,没有延迟的吧!数据长度时44+30个字节?

2、接收端ACK的延迟反馈,一个是随着数据顺带反馈回去,一个是超时反馈回去
a.随着数据顺带反馈回去的时候,接收端实际上也变成了发送端,在默认情况下,是否也会起动Nagle算法?
b.如果是超时反馈的话,这个时间阈值时多少呢?我看有点说是200ms,有的说是40ms,到底应该是多少呢?
...全文
13968 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
random_2011 2015-08-14
  • 打赏
  • 举报
回复
试试iocp
牧草177 2013-10-11
  • 打赏
  • 举报
回复
他这种应答没问题,但是如何编程伪造,俺还真不知道从何入手!
  • 打赏
  • 举报
回复
既然你都抓包了,仔细对照收到的包和应答的包会看出一些关联的 像SYN、ACK这些包是可以伪造的(不然哪来的SYN攻击)
yanchangshan 2013-10-11
  • 打赏
  • 举报
回复
MARK下 以后来看
  • 打赏
  • 举报
回复
抓包可以看到在IP头前面还有一个MAC桢,包含双方的MAC地址 在TCP Header的Flags中,前面6位是保留位,后面几位分别用来设置URG,ACK,PSH,RST,SYN,FIN标识 TCP报头中还有填充位是不定长的,用来保证TCP头是32位的整数倍(有点类似内存对齐) 流量统计中自然应该用数据包的总长度,而不是指数据段的长度(用相应的协议解析包后才能知道) 每个(拆分后)数据包中都有MAC贴,IP头和协议头,里面又包含序列号,ACK对应的序列号,数据段== 所以你上面说的附加长度+数据包*叠加的次数 我认为不对
牧草177 2013-10-11
  • 打赏
  • 举报
回复
其实ACK的发送到底有没启用Nagle其实也不是特别重要!因为我们在编程时,这个无法控制,估计只有研究TCP协议、想对其进行优化的人才会考虑。 要是谁知道如何发送ACK这些底层的数据,欢迎指导!非常想了解! 如果是顺带型的,随着反馈数据一起发送回来,也应该是马上发送出去,因为它已经有发送方的ACK了! 虽然Nagle、ACK延迟、滑动窗口、糊涂综合症,这些我都看过!可是我觉得真正的综合理解,并不是那么简单的,因为网络环境本身就很复杂。 我这里提出来,也只是为了研究,虽然达不到优化TCP协议的程度,但是希望更本质的研究加以利用,最终尝试优化自己的应用程序而已!
  • 打赏
  • 举报
回复
好吧,似乎你是在问,接收方在发送ACK时是否启用了Nagle Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。 个人认为接收方在发送ACK时是没有启用Nagle的,ACK是一种特殊的包,它不同于普通的数据报,并且它需要即时发送以便发送方确认 如果这时启用Nagle,由于ACK包很小,一般就60字节左右,会造成发送延迟,一旦超过发送方的超时时间,发送方会重发之前的数据报,这将导致整个通信效率大幅降低
牧草177 2013-10-11
  • 打赏
  • 举报
回复
“这本书90年代出的,WinSock都不只一个版本,windows与linux等系统内核也不尽相同” 嗯,正时因为这样,所以我就感觉大家说的都好像有道理,但是具体点却都难以说清楚。 所以还是需要自己测试,才清楚。 对于我提出的第一个问题,我自己做了测试,现在把数据贴上,请大家讨论,看看我的理解对不对! 我间隔50ms发送一次数据,数据长度时48字节 首先是不带Nagle算法的 No. Time Source Destination Protocol Length Info 554 31.832502 10.143.63.41 218.65.209.90 TCP 102 17300 > 7600 [PSH, ACK] Seq=625 Ack=1 Win=65535 Len=48 Frame 554: 102 bytes on wire (816 bits), 102 bytes captured (816 bits) Ethernet II, Src: AsustekC_46:75:dd (00:1f:c6:46:75:dd), Dst: FujianSt_b5:b6:cc (00:d0:f8:b5:b6:cc) Internet Protocol Version 4, Src: 10.143.63.41 (10.143.63.41), Dst: 218.65.209.90 (218.65.209.90) Transmission Control Protocol, Src Port: 17300 (17300), Dst Port: 7600 (7600), Seq: 625, Ack: 1, Len: 48 Data (48 bytes) 0000 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 asdasdasdasdasda 0010 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 sdasdasdasdasdas 0020 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 dasdasdasdasdasd 每次数据都是48个字节,但是这里给出了总长度是102,应该是加上了TCP相关协议的数据。 这个102是不是应该记为流量呢?因为在手机编程中,流量也是很重要的参考因素! No. Time Source Destination Protocol Length Info 335 21.582295 10.143.63.41 218.65.209.90 TCP 198 17316 > 7600 [PSH, ACK] Seq=577 Ack=1 Win=65535 Len=144 Frame 335: 198 bytes on wire (1584 bits), 198 bytes captured (1584 bits) Ethernet II, Src: AsustekC_46:75:dd (00:1f:c6:46:75:dd), Dst: FujianSt_b5:b6:cc (00:d0:f8:b5:b6:cc) Internet Protocol Version 4, Src: 10.143.63.41 (10.143.63.41), Dst: 218.65.209.90 (218.65.209.90) Transmission Control Protocol, Src Port: 17316 (17316), Dst Port: 7600 (7600), Seq: 577, Ack: 1, Len: 144 Data (144 bytes) 0000 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 asdasdasdasdasda 0010 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 sdasdasdasdasdas 0020 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 dasdasdasdasdasd 0030 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 asdasdasdasdasda 0040 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 sdasdasdasdasdas 0050 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 dasdasdasdasdasd 0060 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 asdasdasdasdasda 0070 73 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 sdasdasdasdasdas 0080 64 61 73 64 61 73 64 61 73 64 61 73 64 61 73 64 dasdasdasdasdasd 这个是带Nagle算法的,很明显三次的数据叠加在了一起。所以数据总长度由102增加到了198 所以针对我自己提出的关于Nagle的问题。 第一个问题,这个好像是根据ACK来的,没有超时设置 第二和第三个问题,附加长度不是44,比这个跟多,最后的总长度,应该是附加长度+数据包*叠加的次数! 请大家看看,我理解的是否正确!
  • 打赏
  • 举报
回复
引用 13 楼 u012370078 的回复:
200ms就是TCP/IP详解中讲到的,《19TCP的交互数据》! 我的理解是:这个超时时间是固定的,只是并不是在数据到达后才触发,所以ACK回馈的时间是不一定的。 如下是引文:“这些时间之间的差则是200 ms的整数倍,这里所发生的情况是因为T C P使用了一个200 ms的定时器,该定时器以相对于内核引导的200 ms固定时间溢出。由于将要确认的数据是随机到达的(在时刻16.4, 474.3, 831.1等),T C P在内核的200 ms定时器的下一次溢出时得到通知。 这有可能是将来1~200 ms中的任何一刻。”
这个说法表示认同,TCP中有很多种定时器,最常见的超时机制,也是基于定时器的。至于这个200ms,不好深究,这本书90年代出的,WinSock都不只一个版本,windows与linux等系统内核也不尽相同 虽然从结果上看,“Nagle算法完全由TCP协议的ACK机制决定”,但是ACK与Nagle并没有直接关系,前者主要是接收方用来控制收发停等的,后者主要是发送方用来规避过多的小包,提高效率的(但同时也会因为包的拼接带来一点发送延迟) 如果发送方send时给了TCP_NODELAY选项,则禁用Nagle,反之默认情况下是启用的
牧草177 2013-10-11
  • 打赏
  • 举报
回复
但是关于ACK的第一个问题,如果ACK是顺带发回去的?那么是否也会起动Nagle算法呢?
牧草177 2013-10-11
  • 打赏
  • 举报
回复
200ms就是TCP/IP详解中讲到的,《19TCP的交互数据》! 我的理解是:这个超时时间是固定的,只是并不是在数据到达后才触发,所以ACK回馈的时间是不一定的。 如下是引文:“这些时间之间的差则是200 ms的整数倍,这里所发生的情况是因为T C P使用了一个200 ms的定时器,该定时器以相对于内核引导的200 ms固定时间溢出。由于将要确认的数据是随机到达的(在时刻16.4, 474.3, 831.1等),T C P在内核的200 ms定时器的下一次溢出时得到通知。 这有可能是将来1~200 ms中的任何一刻。”
牧草177 2013-10-10
  • 打赏
  • 举报
回复
44个字节是我算错了!应该是40个字节,20个字节的IP首部,20个字节的TCP首部
牧草177 2013-10-10
  • 打赏
  • 举报
回复
上面说的是本地机器应用层到传输层的,应该跟变成语言有关,让我更理解了编程语言的传输具体实现过程,感谢“dongxinxi”! 但是我们好像无法对这个过程进行控制?只有等待write返回才能进行下一步操作! 我所想知道的是,传输层发送出去,TCP这个传输控制协议是怎么通过nagle算法和ACK延迟来协调两个机器之间的数据传输! 还请大家继续讨论
  • 打赏
  • 举报
回复
TCP收发时有一个缓冲区,用来提高系统整体性能 应用程序可通过调用send(write, sendmsg等)利用tcp socket向网络发送应用数据,而tcp/ip协议栈再通过网络设备接口把已经组织成struct sk_buff的应用数据(tcp数据报)真正发送到网络上,由于应用程序调用send的速度跟网络介质发送数据的速度存在差异,所以,一部分应用数据被组织成tcp数据报之后,会缓存在tcp socket的发送缓存队列中,等待网络空闲时再发送出去。同时,tcp协议要求对端在收到tcp数据报后,要对其序号进行ACK,只有当收到一个tcp 数据报的ACK之后,才可以把这个tcp数据报(以一个struct sk_buff的形式存在)从socket的发送缓冲队列中清除。 除了TCP,你还应该了解一下IP协议,默认情况下是会自动分片的(Fragment) 额外的44字节不知道你是通过什么监测的? http://www.cnblogs.com/li-hao/archive/2011/11/21/2257596.html http://ishare.iask.sina.com.cn/f/10466464.html
  • 打赏
  • 举报
回复
引用 1 楼 LADYGAGA_XB 的回复:
我也很想知道这个问题..Mark
+1
牧草177 2013-10-10
  • 打赏
  • 举报
回复
现在要优化程序啊!当然是希望提高啊!
jiaoshiyao 2013-10-10
  • 打赏
  • 举报
回复
管那么多干吗啊 和你写程序有关系么 Socket就可以了 别扯那些没用的 你能这个月的绩效是100那就行
LADYGAGA_XB 2013-10-10
  • 打赏
  • 举报
回复
我也很想知道这个问题..Mark
  • 打赏
  • 举报
回复
所谓的接收端ACK的延迟反馈其实还是上面说的“窗口机制” 何谓窗口,简单地说就是收发多少个包后,接收方才会发送一次ACK 接收方会根据自己缓冲区的容量调整应答包中的窗口大小,发送方收到后,会根据应答包头中的窗口大小来决定“停-等” 以下是引用: 关于持续 流控制问题,现在我们就来讨论这个问题。TCP中实现它的机制是TCP滑动窗口机制。TCP协议使用“重新发送与正向ACK”来保证数据传输的可靠性。发 送方将等待一段时间,如果没有收到其发送的数据包的ACK确认信息,发送方就要重新发送。顺便说一下,TCP协议中有许多定时器。这只是其中一个定时器。 ACK的概念对于流控制是非常重要的,因为TCP滑动窗口协议使TCP的往复确认变得更有效率。如果TCP要发送一个数据包并且等待每一个ACK确认信 息,它实际上就把数据吞吐量削减了一半。 理想的情况是,我们能够一次发送许多数据包,然后等待收到一个确认收到全部数据包的ACK信息,而不用对 方发来更多的数据。但是,我们如何知道发送了多少个数据包呢?TCP窗口尺寸可以控制在“已发送但是没有确认”的状态下能够容纳多少个数据包。如果这个窗 口尺寸很大,我们不必等待ACK信息就可以发送大量的数据包。这实际上就是流控制。 接收方就是控制窗口大小的那一方。如果接收方将窗口大小设为 “0”,那么,发送方根本就不能发送任何数据。如果这个窗口的尺寸是“1”,那么,我们就回到了简单的“发送和等待ACK”的协议。 所以你上面说的什么200ms,40ms都对,也都不对,TCP采用的是滑动窗口,是不固定的,与整个通信的效率有关 http://blog.csdn.net/whygosofar/article/details/5582965
  • 打赏
  • 举报
回复
这是其中一篇的引用资料,希望有帮助 Nagle算法只允许一个未被ACK的包存在于网络,它并不管包的大小,因此它事实上就是一个扩展的停-等协议,只不过它是基于包停-等的,而不是基于字节停-等的。Nagle算法完全由TCP协议的ACK机制决定,这会带来一些问题,比如如果对端ACK回复很快的话,Nagle事实上不会拼接太多的数据包,虽然避免了网络拥塞,网络总体的利用率依然很低。另外,他是一个自适应的方法,读者可以自己按上述规则试验一下。 Nagle算法是silly window syndrome(SWS)预防算法的一个半集。SWS算法预防发送少量的数据,Nagle算法是其在发送方的实现,而接收方要做的时不要通告缓冲空间的很小增长,不通知小窗口,除非缓冲区空间有显著的增长。这里显著的增长定义为完全大小的段(MSS)或增长到大于最大窗口的一半。 注意:BSD的实现是允许在空闲链接上发送大的写操作剩下的最后的小段,也就是说,当超过1个MSS数据发送时,内核先依次发送完n个MSS的数据包,然后再发送尾部的小数据包,其间不再延时等待。(假设网络不阻塞且接收窗口足够大) TCP_NODELAY 选项 默认情况下,发送数据采用Negale 算法。这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Negale 算法。 此时,应用程序向内核递交的每个数据包都会立即发送出去。需要注意的是,虽然禁止了Negale 算法,但网络的传输仍然受到TCP确认延迟机制的影响。 在通信的过程,接收方会根据当前缓冲区的容量,调整TCP报头中的"窗口大小"(不是固定的,也就是你上面问的1.a),以便发送方决定“停-等”,我们只能根据需要设置一些Options,决定要不要用Nagle,并不能直接控制TCP数据包的收发,算法是由操作系统实现的 取不取消Nagle并不会影响到数据报的长度,因为遵循协议的规定,在TCP/IP传输过程中每经过一个协议层都会加上/剔除这个协议的报头 要及时发送,设置TCP_NODELAY选项即可 你好像还是没有好好看 http://www.cnblogs.com/zhaoyl/archive/2012/09/20/2695799.html
加载更多回复(3)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧