
客户端和服务端之间建立连接的三次握手是咋回事? 我们来从java代码运行到观察linux内核来稍微分析一下。
Java代码先准备好上传到linux,server代码在虚拟机node1,client代码在虚拟机node2,从略。下面重点看一下client与server是如何建立连接的。
在server node1机器上抓取网卡(我的虚拟机网卡名是ens33)数据包
tcpdump -nn -i ens33 port 9090

启动服务端

还未accept,等待着输入
启动客户端

上面服务端和客户端都启动以后,看一下node1内核网络状态netstat -natp

可以看出,其中有两个9090端口,一个处理LISTEN监听状态,表示我服务端准备好了,任何客户端都可以来连我了;还有一个是established表示已经建立连接状态,建立连接的双方是192.168.134.128:9090和192.168.134.130:47904,其中192.168.134.128是服务端,端口9090,有一个客户端192.168.134.130来连它并分配了一个随机端口47904。但是,这个连接没有对应的进程PID,(server端还没有accept)。
再来看一下tcpdump抓包情况:

清楚地看到了客户端和服务端建立连接的三次握手。
本次socket的四元组可以看到是
CIP 192.168.134.130 CPORT 47904
SIP 192.168.134.128 SPORT 9090
在server端按回车键,执行accept

accept后发现有Java进程,PID为3862
看下进程3862的文件描述(lsof -p 3862):

6u 建立连接
当客户端一次性向服务端发送超过MTU的字节数时,超过的数据部分将会丢失。
关于MTU维基百科的解释:
最大传输单元(英语:Maximum Transmission Unit,缩写MTU)是指数据链接层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络卡、串口等)。
常见媒体的MTU表
网络 | MTU(Byte) |
|---|---|
超通道 | 65535 |
16Mb/s令牌环 | 17914 |
4Mb/s令牌环 | 4464 |
FDDI | 4352 |
以太网 | 1500 |
IEEE 802.3/802.2 | 1492 |
X.25 | 576 |
点对点(低时延) | 296 |
查看本机网口的mtuifconfig

本机ens33网络mtu为1500,测试一下一次性发送超过1500个字节的情况
服务端等待接收消息(阻塞住了,还未accept)

客户端发送数据,随便粘贴一段文字,最后输入自己认得的1111111,

这个时候netstat -natp看一下连接情况

如图可知,此时接内核已接收了1152个,服务器还未accept,继续发送一段字符abcdefg,查看netstat -natp内核接收的还是1152个数据包,这时,让server端accept,发现接收到的数据后面的都丢失了。
TCP是面向连接的,可靠地传输协议(三次握手),内核级开辟资源。 Socket四元组:
Client IP,Client Port,Server IP,Server Port,这四个元素能让一个连接变得清晰、唯一。
- END -