课程中三次握手疑问?

来源:8-3 TCP三次握手

慕虎7125121

2019-11-04

个人对三次握手有些疑问,希望老师能够给予答惑。

下面是本人原来的理解:
如三次握手流程图(图二)所示,
第一次握手:应该处在客户端从(CLOSE状态)向(SYS_SENT状态)迁移的过程中(而不是SYS_SENT状态),此时发出SYN信号。
第二次握手:应该处在服务端从(LISTEN状态)向(SYS_RECV)迁移过程中(而不是SYS_RECV状态),此时服务端接收SYN,发送SYN和ACK,(注:此时应该与accept阻塞无任何关系才对,因为此时处在协议中,并不涉及外部的API)
第三次握手:客户端处在(SYS_SENT状态)向(ESTABLISHED状态)迁移过程中发出ACK,服务器处在(SYS_RECV状态)向(ESTABLISHED状态)迁移过程中,接收ACK。

换句话说,三次握手时协议栈内部的操作,在外部API看来,应该处在LISTEN------->ACCEPT过程中,而不应该有accept阻塞。等三次握手结束后,才能利用API,accept函数将socket句柄从协议栈内部取出来给上层用户使用,accept本身应该不参与三次握手才对。

上面只是我个人的理解,希望老师批评指针,期待回复

课程中三次握手:
图片描述

图二:三次握手流程:

图片描述

写回答

1回答

李超

2019-11-23

这个图可能稍微有一点问题,会产生一些奇异,不过没有太大的问题。客户一开始是 Close 状态,这里写成 CLOSED 更合适些,在调用 connect() 函数后,变为了 SYN_SENT 状态。

对于服务端来说,一开始也是 Close(CLOSED) 状态,调用listen()后,变为 LISTEN 状态。这时,在服务端会调用 accpet() 函数,accept() 是一个用户层 API,如果是阻塞模式, 它会检测连接队列中是否有已建立好的连接,如果没有它会进行睡眠。

当内核层有连接建立成功后,会从 accept 唤醒。你可以结合下面的代码再理解一下。

注: 对于非阻塞模式 accept 调用就不是这个流程了。

```

  ...

  ret = listen(socket_fd, backlog);

  if ( ret == -1 ){

    perror("listen error");

    exit(1);

  }

  //loop

  for(;;){

    int addr_len = sizeof( struct sockaddr_in );

    //accept an new connection

    accept_fd = accept( socket_fd, (struct sockaddr *)&remote_addr, &addr_len );

    for(;;){

        ......

    }

    ...

}

```

0
0

百万级高并发WebRTC流媒体服务器设计与开发

备战5G音视频时代,抢先掌握服务端高级技能

2067 学习 · 375 问题

查看课程