Chinaunix

标题: tcp三次握手,客户端发送最后一个ack时可以带数据? [打印本页]

作者: mrpre    时间: 2014-09-24 23:09
标题: tcp三次握手,客户端发送最后一个ack时可以带数据?
我在大学那本网络教材中看到了,但是rfc上找了好久没找到,不知道哪位知道呢个rfc上明确提到了这点。。。
感激不尽!
作者: mrpre    时间: 2014-09-24 23:10
教材上讲三次握手时,说可以携带数据,rfc上实在是没看出痕迹啊,英语不好,不知道哪位兄弟知道具体哪个rfc上有,告诉哥们一声
作者: Tinnal    时间: 2014-09-24 23:55
http://stackoverflow.com/questions/3437569/tcpip-3-way-handshake
http://www.perlmonks.org/?node_id=910007
作者: 流氓无产者    时间: 2014-09-25 09:34
可以吧,自己抓包看一下,就印象深刻了
作者: mrpre    时间: 2014-09-25 14:19
本帖最后由 mrpre 于 2014-09-25 14:20 编辑

回复 3# Tinnal


多谢哈,我也在RFC793中找到了线索。

If the state is SYN-SENT then
    first check the ACK bit
..........
...........
.........
change the connection state to ESTABLISHED, form an ACK segment

         <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

        and send it.  

      Data or controls which were queued for  transmission may be included



作者: mrpre    时间: 2014-09-25 16:35
构造三次握手最后一个ack带数据的socket代码,参考网上修改的,可以运行,并且验证成功。
  1. int main(int argc,char **argv)
  2. {
  3.         int listenfd,connfd,opt=1;
  4.         pid_t childpid;
  5.         int i;
  6.         socklen_t clilen;
  7.         struct sockaddr_in servaddr;
  8.         struct sockaddr_in realaddr;
  9.                 char GET[]="GET / HTTP/1.0\r\n\r\n";
  10.                 char msg[1024]={0};
  11.                
  12.         if (argc != 3) {
  13.                 printf("usage: %s serverip serverport\n", argv[0]);
  14.                 return 0;
  15.         }   
  16.         if ((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
  17.                 printf("socket error errno=%d", errno);

  18.         opt = 1;
  19.         setsockopt(listenfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &opt, sizeof(opt));

  20.         bzero(&realaddr,sizeof(realaddr));
  21.         realaddr.sin_family=AF_INET;
  22.         realaddr.sin_port=htons(atoi(argv[2]));
  23.         inet_pton(AF_INET,argv[1],&realaddr.sin_addr);
  24.         if (connect(listenfd,(struct sockaddr*)&realaddr,sizeof(realaddr))==-1)
  25.                 printf("connect error errno=%d", errno);
  26.                                
  27.                 printf("ready to send\n");
  28.         send(listenfd,GET,sizeof(GET),0);
  29.                 printf("Testing server\n");
  30.                 if(0 == recv(listenfd,msg,500,0))
  31.                 {
  32.                         printf("read fin\n");
  33.                         sleep(1);
  34.                         close(listenfd);
  35.                 }
  36.                
  37.                 printf("Server is Standard\n");
  38.                
  39. }
复制代码

作者: inurl    时间: 2014-09-25 16:47
  准确的说, 下次的数据里面可以包含上次的ack。
作者: sqm2050    时间: 2015-12-22 10:23
讲很对,rfc没有具体看到,但是《http权威指南》P88 里看到了这么一句:由于确认报文很小,所以TCP允许在发往相同方向的的输出数据分组中对其进行“捎带”。
   
作者: nswcfd    时间: 2015-12-22 15:41
怎么保证的?靠TCP_DEFER_ACCEPT?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2