由三道关于三路握手的面试题来深入理解socket编程

三道经典的面试题

最近经常看到别人分享的关于网络通信socket三路握手的三道面试题, 之前看到时也不是很了解, 接下来通过代码和wireshark抓包来深入理解他们:

1, 在编写socket服务器端程序时,socket三路握手时在什么时候完成的?
2, listen()函数中第二个参数backlog的含义?
3, 客户端在进行三路握手时,出现异常将会收到什么报文?

服务器三路握手什么时候完成?

对于第一个问题, 按照自己之前的理解, 认为服务器端的三路握手时在accept()时完成的. 接下来我们通过代码和wireshark来抓包验证.

首先修改服务器程序, 在调用accept()之前加一个100s的延时, 在服务器休眠完成之前使用客户端连接, 同时启动wireshark开始抓包, 看是否能够完成三路握手.服务器端代码如下:
在这里插入图片描述

客户端进行连接, wireshark抓包结果:
在这里插入图片描述
我们可以观察到服务器端没有调用accept()函数, 通过抓包看到已经完成了三路握手, 证明了我们初步的想法是错误的.

接下来查阅 《unix网络编程》 这本书来看accept()函数的说明.
在这里插入图片描述
我们往前翻阅, 可以看到listen()函数中涉及到未完成连接队列已完成连接队列, 以下为书中内容:
在这里插入图片描述
通过查阅, 我们可以得知, accept()函数在已完成连接队列列头返回下一个已完成连接,
服务器三路握手在listen()函数之后, accept()之前, 由内核来自动完成了三路握手.


listen()函数中第二个参数的含义?

在我们socket服务器端代码中, 调用socket, bind 之后, 服务器默认时主动连接模式, 此时调用listen函数.
listen()函数: 当socket创建一个套接口时, 它默认欸主动套接口, listen函数将未连接的套接口转换未被动套接口(即服务器变为被动连接模式), 第二个参数规定了内核未此套接口排队的最大连接个数. 书中内容如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过listen()函数的backlog参数中, backlog的值是已完成连接队列未完成连接队列之和(不包括accept之后拿出去的), 未完成连接条目有75秒的超时时间, 有模糊因子的存在, 最大值为乘以1.5, backlog值一般设置为13, 即最多可以有16个客户端.


客户端在进行三路握手时,出现异常将会收到什么报文?

对于这个问题, 我们在第一个问题中已经找到了三路握手的发生是在调用listen()函数之后, accept()函数之前.
对于这个问题, 首先修改服务器端代码, 在listen()函数之前给一个while(1) 死循环, 让他休眠! 我们通过客户端去连接, 同时启动wireshark开始抓包, 观察现象: 服务器端部分代码如下:
在这里插入图片描述

客户端进行连接, wireshark抓包结果:
在这里插入图片描述
通过观察现象可以发现, 我们在服务器端listen()函数之前进入死循环, 这时通过TCP Test Tool 客户端进行连接, 发生了三路握手中的第一次握手, 客户端发送了一个 SYN = 1, 此时三路握手发生异常, 服务器端给客户端发送 RST = 1, ACK = 1 的一个报文, 进行重连, 通过抓包可以看到一共重连了5次!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值