Java TCP/IP协议
TCP/IP协议栈是互联网通信的基础,TCP提供可靠的面向连接服务。
TCP/IP分层模型
| 层次 | 协议 | 作用 |
|---|---|---|
| 应用层 | HTTP, FTP, SMTP | 业务数据 |
| 传输层 | TCP, UDP | 端到端传输 |
| 网络层 | IP, ICMP | 路由寻址 |
| 链路层 | Ethernet, WiFi | 物理传输 |
TCP与UDP对比
| 特性 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接 | 无连接 |
| 可靠性 | 可靠传输 | 不可靠 |
| 顺序 | 保证顺序 | 不保证 |
| 流量控制 | 有 | 无 |
| 速度 | 较慢 | 较快 |
| 适用场景 | 文件传输、Web | 实时音视频、DNS |
TCP三次握手
建立连接需要三次握手:
Java
客户端 服务端
| |
|─────── SYN ───────────→| 第一次:请求建立连接
| (seq=x) |
| |
|←────── SYN+ACK ────────| 第二次:确认并请求
| (seq=y, ack=x+1) |
| |
|─────── ACK ───────────→| 第三次:确认连接
| (ack=y+1) |
| |
========== 连接建立 ==========
握手过程
Java
// 客户端视角
Socket socket = new Socket();
socket.connect(new InetSocketAddress("server", 8888));
// 内部完成三次握手
// 服务端视角
ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
// accept()返回表示三次握手完成
TCP四次挥手
断开连接需要四次挥手:
Java
客户端 服务端
| |
|─────── FIN ───────────→| 第一次:请求断开
| |
|←────── ACK ────────────| 第二次:确认断开请求
| |
| | 服务端可能还有数据发送
|←────── FIN ────────────| 第三次:服务端请求断开
| |
|─────── ACK ───────────→| 第四次:确认断开
| |
========== 连接关闭 ==========
###挥手过程
Java
socket.close(); // 发起FIN包,开始四次挥手
TCP可靠传输机制
1. 序列号与确认
每个TCP报文都有序列号,接收方通过ACK确认已收到的数据。
2. 重传机制
Java
// 超时重传
socket.setSoTimeout(5000); // 设置读超时,触发重传
3. 流量控制
通过滑动窗口控制发送速率,避免接收方缓冲溢出。
4. 拥塞控制
网络拥塞时降低发送速率,算法包括慢启动、拥塞避免。
TCP参数调优
Java
Socket socket = new Socket();
// 连接超时
socket.connect(address, 5000); // 5秒连接超时
// 读超时(SO_TIMEOUT)
socket.setSoTimeout(3000); // 3秒读超时
// 发送缓冲区大小
socket.setSendBufferSize(64 * 1024); // 64KB
// 接收缓冲区大小
socket.setReceiveBufferSize(64 * 1024); // 64KB
// 禁用Nagle算法(减少小包延迟)
socket.setTcpNoDelay(true);
// 保持连接
socket.setKeepAlive(true);
// 关闭时立即释放资源
socket.setSoLinger(true, 0); // 立即关闭,不等待
IP地址与端口
text
// IPv4地址
InetAddress ipv4 = InetAddress.getByName("192.168.1.1");
// IPv6地址
InetAddress ipv6 = InetAddress.getByName("fe80::1");
// 本机地址
InetAddress local = InetAddress.getLocalHost();
// 端口范围:0-65535
// 0-1023:系统保留端口(如HTTP 80, SSH 22)
// 1024-49151:注册端口
// 49152-65535:动态端口
Socket状态
text
socket.isConnected(); // 是否已连接
socket.isBound(); // 是否已绑定地址
socket.isClosed(); // 是否已关闭
socket.isInputShutdown(); // 输入流是否关闭
socket.isOutputShutdown();// 输出流是否关闭
// 半关闭:只关闭输出,仍可接收数据
socket.shutdownOutput(); // 发送FIN,但保持接收能力
注意事项
TCP三次握手必须完成才能开始数据传输
服务端accept() 阻塞等待连接完成
设置超时很重要,防止无限阻塞等待
close() 发起四次挥手,需等待对方确认
大量短连接可能耗尽端口资源,需复用连接
要点总结
- TCP面向连接、可靠传输,UDP无连接、不可靠
- 三次握手建立连接:SYN → SYN+ACK → ACK
- 四次挥手断开连接:FIN → ACK → FIN → ACK
- 可靠传输依赖序列号、确认、重传、流量控制
- 合理设置超时和缓冲区大小优化性能
📝 发现内容有误?点击此处直接编辑