为什么我TCP发送一个包,对方就回一个ACK?

sherlock_lai 2009-04-01 07:53:59
而另一个软件发两个TCP包,目标才回一个ACK,要怎么控制?
...全文
1198 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sherlock_lai 2009-04-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 KevinCao 的回复:]
楼上回答的全是一群装B人士,基本上没有去写过基础代码的一帮所谓的专家乱说

楼主的这个问题,其实不是问题,你要理解TCP的实现原理与工作机制,TCP是一个流协议,在你通过TCP发一个包,按照TCP的协议,TCP实现层会通知你ACK的应答,但是这个包是一个数据流,也就是说有可能你连接发多个应用层数据包,在TCP层可能会是一个数据流,所以你就只会看到TCP只回一个ACK给你,这种情况在测试环境下,比如内网速度很快的情况是经常会…
[/Quote]
实际上就是FIN,ACK,RST在编程中的产生的一些细节问题,而不是说概念。先结贴了,有机会我再调试那段代码的时候再讨论。
morris88 2009-04-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 KevinCao 的回复:]
楼上回答的全是一群装B人士,基本上没有去写过基础代码的一帮所谓的专家乱说

楼主的这个问题,其实不是问题,你要理解TCP的实现原理与工作机制,TCP是一个流协议,在你通过TCP发一个包,按照TCP的协议,TCP实现层会通知你ACK的应答,但是这个包是一个数据流,也就是说有可能你连接发多个应用层数据包,在TCP层可能会是一个数据流,所以你就只会看到TCP只回一个ACK给你,这种情况在测试环境下,比如内网速度很快的情况是经常会…
[/Quote]

要与时俱进耶,不要只停留在《TCP/IP详解》3卷上,网络发展日新月异。
其中 SACK 作为 tcp 协议的补充,提供了选择性应答方式,不需要每个报文都应答啊。貌似就可以达到楼主描述的现象与结果。象 setsockopt 跟 getsockopt 都已经支持了SACK了,下面是摘抄的部分片段:

j = sizeof(int);
if (no_sack != -1) {
if (setsockopt(fd, proto->p_proto,
TCP_DO_SACK, (char *)&no_sack, j) < 0)
perror("disable/enable SACKs for all connections");

if (getsockopt(fd, proto->p_proto,
TCP_DO_SACK, (char *)&tno_sack, &j) < 0)
perror("disable/enable SACK for all connections");
if (no_sack != tno_sack)
printf("no_sack != tno_sack");
}
超龄编码人 2009-04-05
  • 打赏
  • 举报
回复
楼上高人
KevinCao 2009-04-05
  • 打赏
  • 举报
回复
楼上回答的全是一群装B人士,基本上没有去写过基础代码的一帮所谓的专家乱说

楼主的这个问题,其实不是问题,你要理解TCP的实现原理与工作机制,TCP是一个流协议,在你通过TCP发一个包,按照TCP的协议,TCP实现层会通知你ACK的应答,但是这个包是一个数据流,也就是说有可能你连接发多个应用层数据包,在TCP层可能会是一个数据流,所以你就只会看到TCP只回一个ACK给你,这种情况在测试环境下,比如内网速度很快的情况是经常会发生的,特别是在程序内部逻辑时间间隔短,发送又很快的情况下,所以来说这个是正常的,不要担心,只要你的应用层一定要想办法把这段数据流分开就可以了


morris88 2009-04-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sherlock_lai 的回复:]
已经和对方完成s->a,s->a的握手,
但是我每发一个带有效数据的TCP包,服务器都要回一个ack,(服务器并不回发有效数据)

而我使用另一个现成的软件作为客户端,那个软件要发两个带有效数据的TCP包,服务器才回一个ack!
window size都是一样的

不知道各位明白我的意思没有?
[/Quote]


使用选择性报文回应(SACK系列)就可以完成这个功能!
sherlock_lai 2009-04-03
  • 打赏
  • 举报
回复
已经和对方完成s->a,s->a的握手,
但是我每发一个带有效数据的TCP包,服务器都要回一个ack,(服务器并不回发有效数据)

而我使用另一个现成的软件作为客户端,那个软件要发两个带有效数据的TCP包,服务器才回一个ack!
window size都是一样的

不知道各位明白我的意思没有?
sherlock_lai 2009-04-03
  • 打赏
  • 举报
回复
已经和对方完成s->a,s->s的握手,
但是我每发一个带有效数据的TCP包,服务器都要回一个ack,(服务器并不回发有效数据)

而我使用另一个现成的软件作为客户端,那个软件要发两个带有效数据的TCP包,服务器才回一个ack!
window size都是一样的

不知道各位明白我的意思没有?
  • 打赏
  • 举报
回复
楼主理解有误.
独孤过儿 2009-04-02
  • 打赏
  • 举报
回复
去看RFC 793,那裏面寫的很清楚
sayigood 2009-04-02
  • 打赏
  • 举报
回复
不太明白你的问题 估计是你的理解有误。
tcp握手过程:
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
morris88 2009-04-02
  • 打赏
  • 举报
回复
/proc/sys/net/ipv4/tcp_sack "1" 启用有选择的应答(Selective Acknowledgment),这可以通过有选择地应答乱序接收到的报文来提高性能(这样可以让发送者只发送丢失的报文段);(对于广域网通信来说)这个选项应该启用,但是这会增加对 CPU 的占用。
/proc/sys/net/ipv4/tcp_fack "1" 启用转发应答(Forward Acknowledgment),这可以进行有选择应答(SACK)从而减少拥塞情况的发生;这个选项也应该启用。
once_and_again 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fetag 的回复:]
去看RFC 793,那裏面寫的很清楚
[/Quote]

rfc 一看就是高人
morris88 2009-04-01
  • 打赏
  • 举报
回复
启用SACK。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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