继续探讨关于TCP编程中ACK的奇怪问题,高手请进(有详细抓包过程)

sherlock_lai 2009-04-06 02:52:47
我的目的是要利用ISCSI协议和server端进行通信。 client和server在WINDOWS中都有现成的软件(MICROSOFT ISCSI INITIATOR和ISCSI CAKE),而我是要模拟client的功能(我的client程序放在arm中跑)。本人网络编程应该算入门了,写过一些网络编程的代码。但是这个问题真的比较奇怪,百思不得其解,google也找不到答案。

首先看现成软件的正确的通信过程1:
包1:FLAG(SYN) 方向(C->S) SEQ(2304958692) ACK(0) 大小(74)
包2:FLAG(ACK+SYN) 方向(S->C) SEQ(3902452458) ACK(2304958693) 大小(78)
包3:FLAG(ACK) 方向(C->S) SEQ(2304958693) ACK(3902452459) 大小(66) (握手握好了)
包4:FLAG(ACK+PSH) 方向(C->S) SEQ(2304958693) ACK(3902452459) 大小(114)(发送了一个命令头,内容部不贴了,就叫它头1吧)
包5:FLAG(ACK+PSH) 方向(C->S) SEQ(2304958741) ACK(3902452459) 大小(290)(发送了一个命令数据,简称数据1)
包6:FLAG(ACK) 方向(S->C) SEQ(3902452459) ACK(2304958965) 大小(66)
包7:FLAG(ACK+PSH) 方向(S->C) SEQ(3902452459) ACK(2304958965) 大小(114)(返回一个命令头,头2)
包8:FLAG(ACK) 方向(C->S) SEQ(2304958965) ACK(3902452507) 大小(66)
包9:FLAG(ACK+PSH) 方向(S->C) SEQ(3902452507) ACK(2304958965) 大小(186)(返回一个数据头,数据2)(正确的通信会收到头2的数据2)

然后是我写的程序的通信过程2:
包1:FLAG(SYN) 方向(C->S) SEQ(306076103 ) ACK(0) 大小(74)
包2:FLAG(ACK+SYN) 方向(S->C) SEQ(741538317 ) ACK(306076104 ) 大小(78)
包3:FLAG(ACK) 方向(C->S) SEQ(306076104 ) ACK(741538318 ) 大小(66) (握手也握好了)
包4:FLAG(ACK+PSH) 方向(C->S) SEQ(306076104 ) ACK(741538318 ) 大小(114)(发送了一个命令头,内容和正确通信绝对是一样的!)
包5:FLAG(ACK) 方向(S->C) SEQ(741538318 ) ACK(306076152 ) 大小(66)
包6:FLAG(ACK+PSH) 方向(C->S) SEQ(306076152 ) ACK(741538318 ) 大小(290)(发送了一个命令数据,和正确通信业绝对是一样的!)
包7:FLAG(ACK+PSH) 方向(S->C) SEQ(741538318 ) ACK(306076376 ) 大小(114)(返回一个命令头,头2,到此结束,头2的格式不正确,通信不成功)


问题:过程1和过程2没有随机性,每次测试,结果都是一样的(当然每次测试SEQ和ACK的初始值不一样)。过程2和过程1唯一不同的地方就是,在过程2中,我发了包4,SERVER马上就回了相应的包5,然后我才发包6(我是调用两次send)。而在过程1中,client连续发了包4和包5,然后server回应一个包6。这个就是奇怪的地方,这个client是如何做到连续发了包4和包5?它的包5是怎么产生的?在程序中要怎么设置?(注意包5的SEQ,它并不是之前的包的回应)
注:请不要叫我去看什么TCP/IP详解,如果人人都有时间时不时的把那书再查一遍,CSDN就没有存在的意义了。
...全文
362 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuna418 2009-08-10
  • 打赏
  • 举报
回复
楼主,我最近在和你做同样的事情,也遇到了好多的问题!
希望能得到您的教导!
我QQ:815895768
期待得到您的回复!
sherlock_lai 2009-04-07
  • 打赏
  • 举报
回复
解决了!恶心啊。。。
竟然关闭nagle就可以使得两个包连续发了。
但是还是和initiator软件略有不同,不知道它还设置了什么东西。不过已经能够通信了。
谢谢各位参与讨论。
独孤过儿 2009-04-06
  • 打赏
  • 举报
回复
如果可以,請抓wireshark的log上來,我對你寫的這個過程不感冒...
morris88 2009-04-06
  • 打赏
  • 举报
回复
是否可以将其详细的dump packet情况贴上来,包括时间、option等!
sherlock_lai 2009-04-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 morris88 的回复:]
貌似前一个软件是这样实现(伪码):

C/C++ code
{
send(头1);
send(数据1);
recv();
}
[/Quote]
我就是连续两次send,中间没其他代码 而且系统只运行了这个程序,但是server就是要先回个ACK
  • 打赏
  • 举报
回复
然后我才发包6(我是调用两次send)。而在过程1中,client连续发了包4和包5,然后server回应一个包6。这个就是奇怪的地方,这个client是如何做到连续发了包4和包5?它的包5是怎么产生的?在程序中要怎么设置?(注意包5的SEQ,它并不是之前的包的回应)


连续2次send倒是全部可以发到缓冲区.只要没有发生数据交叉的话,那server可以从缓冲区正确的解析.
morris88 2009-04-06
  • 打赏
  • 举报
回复
貌似前一个软件是这样实现(伪码):

{
send(头1);
send(数据1);
recv();
}
morris88 2009-04-06
  • 打赏
  • 举报
回复
发送的很快时,也就是在对方推迟发送ACK前,就发送数据1!
sherlock_lai 2009-04-06
  • 打赏
  • 举报
回复
楼上的 那怎么产生正确通信过程中的包5?
morris88 2009-04-06
  • 打赏
  • 举报
回复
通常T C P在接收到数据时并不
立即发送A C K;相反,它推迟发送,以便将A C K与需要沿该方向发送的数据一起发送(有时
称这种现象为数据捎带A C K)。绝大多数实现采用的时延为200 ms,也就是说,T C P将以最大
200 ms 的时延等待是否有数据一起发送。

23,121

社区成员

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

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