课程中三次握手疑问?
来源: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(;;){
......
}
...
}
```
00
相似问题