声明
文中提到的应用程序特指JAVA应用程序
本文涉及的Linux基础命令
netstat -natp 查看端口相关信息
lsof -p pid 查看某个进程打开的fd相关信息
ls -l /proc/pid/fd 查看某个进程打开的fd相关信息
什么是TCP
TCP是一种面向连接的、可靠的传输协议
Client(客户端)和 Server(服务端)建立连接需要经过三次握手,断开连接需要完成四次挥手
什么是Socket
Linux一切皆文件,Socket是其中一种文件类型
ls -l /proc/pid/fd 查看某个进程的fd可以看到socket文件类型
- lrwx------. 1 root root 64 Dec 13 16:42 4 -> socket:[3848983]
- lrwx------. 1 root root 64 Dec 13 16:42 5 -> socket:[3848985]
socket可以简单理解为ServerIP;ServerPort + ClientIP;ClientPort 这样一个四元组组成
端口的最大限制:65535
单进程fd数量限制:根据Linux系统用户的不同,可以修改不同的数量限制,使用ulimit -a 命令查询
ulimit -a
open files (-n) 1024
pipe size (512 bytes, -p) 8
查询所有进程已经使用的fd数量和允许使用的最大fd数量
cat /proc/sys/fs/file-nr
2048 0 585916
建立Socket连接时应用程序和内核的工作状况
应用程序间相互传输数据都需要经过内核
三次握手、四次挥手都是Server内核和Client内核之间进行的,不经过应用程序
内核为每个连接都设置了发送队列(缓冲区)和接收队列(缓冲区),当系统来不及处理数据时,会暂存在缓冲对列中,当超过缓冲队列大小时,新来的数据会被抛弃
通过netstat 命令可以看到发送队列(Send-Q)和接收队列(Recv-Q)中数据的大小
netstat -natp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 1 0 :::9090 :::* LISTEN 4877/java
tcp6 18 0 10.188.40.230:9090 10.188.40.231:51438 ESTABLISHED -
如下图所示,Server服务部署在230机器,Client部署在231机器,231连接230,具体步骤如下:
- 230服务启动,端口9090,内核分配fd5给230APP,fd5 处于LISTEN状态,等待连接
- 231 应用程序执行 Socket client = new Socket("10.188.21.230",9090);
- 231内核为231应用程序分配端口45372
- 231内核与230内核建立socket连接,返回fd8,fd8绑定给231APP
- 230 APP调用accept,接收到231的连接,返回fd6绑定到230APP
- 231 fd8 与 230 fd6 开始传输数据
传输数据包大小
数据包传输大小限制通过ifconfig 命令查看MTU
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
实际传输的数据包大小通过tcpdump 抓包得到mss
Flags [S], seq 1457962801, win 29200, options [mss 1460,sackOK,TS val 1683212710 ecr 0,nop,wscale 7], length 0