Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题(11)
所以 , 监听的 socket 和真正用来传送数据的 socket , 是「两个」 socket , 一个叫作监听 socket , 一个叫作已完成连接 socket 。
成功连接建立之后 , 双方开始通过 read 和 write 函数来读写数据 , 就像往一个文件流里面写东西一样 。
listen 时候参数 backlog 的意义?
Linux内核中会维护两个队列:
- 未完成连接队列(SYN 队列):接收到一个 SYN 建立连接请求 , 处于 SYN_RCVD 状态;
- 已完成连接队列(Accpet 队列):已完成 TCP 三次握手过程 , 处于 ESTABLISHED 状态;
本文插图
SYN 队列 与 Accpet 队列
int listen (int socketfd, int backlog)
- 参数一 socketfd 为 socketfd 文件描述符
- 参数二 backlog , 这参数在历史有一定的变化
在 Linux 内核 2.2 之后 , backlog 变成 accept 队列 , 也就是已完成连接建立的队列长度 , 所以现在通常认为 backlog 是 accept 队列 。
accept 发送在三次握手的哪一步?
我们先看看客户端连接服务端时 , 发送了什么?
本文插图
客户端连接服务端
- 客户端的协议栈向服务器端发送了 SYN 包 , 并告诉服务器端当前发送序列号 client_isn , 客户端进入 SYNC_SENT 状态;
- 服务器端的协议栈收到这个包之后 , 和客户端进行 ACK 应答 , 应答的值为 client_isn+1 , 表示对 SYN 包 client_isn 的确认 , 同时服务器也发送一个 SYN 包 , 告诉客户端当前我的发送序列号为 server_isn , 服务器端进入 SYNC_RCVD 状态;
- 客户端协议栈收到 ACK 之后 , 使得应用程序从 connect 调用返回 , 表示客户端到服务器端的单向连接建立成功 , 客户端的状态为 ESTABLISHED , 同时客户端协议栈也会对服务器端的 SYN 包进行应答 , 应答数据为 server_isn+1;
- 应答包到达服务器端后 , 服务器端协议栈使得 accept 阻塞调用返回 , 这个时候服务器端到客户端的单向连接也建立成功 , 服务器端也进入 ESTABLISHED 状态 。
客户端调用 close 了 , 连接是断开的流程是什么?
我们看看客户端主动调用了 close , 会发生什么?
本文插图
客户端调用 close 过程
- 客户端调用 close , 表明客户端没有数据需要发送了 , 则此时会向服务端发送 FIN 报文 , 进入 FIN_WAIT_1 状态;
- 服务端接收到了 FIN 报文 , TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中 , 应用程序可以通过 read 调用来感知这个 FIN 包 。 这个 EOF 会被放在已排队等候的其他已接收的数据之后 , 这就意味着服务端需要处理这种异常情况 , 因为 EOF 表示在该连接上再无额外数据到达 。 此时 , 服务端进入 CLOSE_WAIT 状态;
- 接着 , 当处理完数据后 , 自然就会读到 EOF , 于是也调用 close 关闭它的套接字 , 这会使得会发出一个 FIN 包 , 之后处于 LAST_ACK 状态;
- 客户端接收到服务端的 FIN 包 , 并发送 ACK 确认包给服务端 , 此时客户端将进入 TIME_WAIT 状态;
推荐阅读
- 『Java』java数据结构系列——什么是数据结构
- 『Java』马云:成功人跟普通人差不多,但这三点我一定要分享给所有年轻人
- 小谢娱乐哦引来广大网友狂点赞,直呼炸天,程序员用Java实现扫雷小游戏
- 「客户端」学习网络编程,不了解TCP协议?难怪面试被刷下去,还不来学习!
- 体坛焦点全场吊打对手,上港苦主独造三球,4-0狂胜!申花亚冠劲敌踢疯了
- #Java#java线程到底有多少种状态?
- 【皇室战争】皇室战争:狂暴模式被吊打?学会这套卡组,轻松连胜拿奖励
- Muster电竞单挑省级马超惨遭吊打,网友:真香,国服瑶妹打脸梦泪失败
- 星空游戏精选小羊火龙溢出严重,法师吊打满配物理队?明日方舟高台输出太强
- #智能手表#1、初识java-1
