计算机网络复习计划 - Java开发方向
学习者背景
- 当前职业:Java开发工程师
- 学习目标:系统复习计算机网络知识,与Java开发工作深度结合
- 学习周期:12周(3个月)
学习方法论
学习原则
- 理论结合实践:每个知识点都要找到在Java开发中的实际应用场景
- 问题驱动:从工作中遇到的实际网络问题出发
- 工具辅助:使用抓包工具、网络诊断工具加深理解
- 代码验证:用Java代码验证网络协议的运作机制
推荐学习资源
- 书籍:《计算机网络(第8版)》谢希仁、《图解TCP/IP》
- 在线课程:Coursera斯坦福大学计算机网络
- 实践工具:Wireshark、tcpdump、Netty、Socket编程
- Java网络库:java.net包、Netty、OkHttp、Apache HttpClient
第一阶段:网络基础与物理层(第1-2周)
第1周:计算机网络概述与分层模型
学习目标
- 理解计算机网络的基本概念和发展历史
- 掌握OSI七层模型和TCP/IP四层模型
- 理解分层设计的哲学
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | 网络基本概念 | 交换方式、性能指标 | 理解Java应用中的网络延迟概念 |
| 周二 | OSI七层模型 | 各层功能、封装与解封装 | 分析Java Socket涉及的层次 |
| 周三 | TCP/IP模型 | 四层结构、与OSI对比 | 理解Java应用在TCP/IP中的位置 |
| 周四 | 协议与服务 | PDU、协议栈概念 | 分析HTTP协议栈在Java中的实现 |
| 周五 | 实践练习1 | 使用Wireshark抓包分析 | 抓取Java应用的网络包 |
| 周六 | 实践练习2 | 分析HTTP请求响应 | 使用Java发送HTTP请求并抓包分析 |
| 周日 | 总结复习 | 整理笔记、绘制思维导图 | 总结分层模型在开发中的意义 |
详细学习内容
周一:网络基本概念
1. 计算机网络定义与发展
- 从单机到网络:为什么需要网络
- 网络发展的三个阶段:面向终端的计算机网络、计算机-计算机网络、开放式标准化网络
- Internet的发展历史:ARPANET → NSFNET → Internet
2. 数据交换方式
- 电路交换:建立连接→传输数据→释放连接
- 报文交换:存储转发,报文作为整体
- 分组交换:将报文分成分组,独立传输再组装
- Java思考:理解为什么HTTP是面向无连接的(分组交换思想)
3. 网络性能指标
- 速率:b/s、kb/s、Mb/s、Gb/s
- 带宽:单位时间内能通过的数据量
- 吞吐量:实际通过的数据量
- 时延:发送时延、传播时延、处理时延、排队时延
- 时延带宽积
- 往返时间RTT(Round-Trip Time)
- 利用率:信道利用率、网络利用率
- Java思考:
System.currentTimeMillis()测量RTT的意义
周二:OSI七层模型
1. 七层结构详解
┌─────────────────────────────────┐
│ 7. 应用层 (Application) │ 用户接口,为应用程序提供服务
├─────────────────────────────────┤
│ 6. 表示层 (Presentation) │ 数据格式化、加密解密
├─────────────────────────────────┤
│ 5. 会话层 (Session) │ 建立、管理、终止会话
├─────────────────────────────────┤
│ 4. 传输层 (Transport) │ 端到端通信,TCP/UDP
├─────────────────────────────────┤
│ 3. 网络层 (Network) │ 路由选择,IP协议
├─────────────────────────────────┤
│ 2. 数据链路层 (Data Link) │ 帧同步、差错控制
├─────────────────────────────────┤
│ 1. 物理层 (Physical) │ 比特流传输
└─────────────────────────────────┘
2. 封装与解封装过程
- 发送方:数据→逐层添加头部→最终形成比特流
- 接收方:比特流→逐层解析头部→最终获得数据
- PDU(Protocol Data Unit):每层的数据单位
3. Java结合
java.net.Socket工作在传输层之上- 应用程序主要关心应用层和传输层
- 理解为什么Java网络编程不需要关注底层
周三:TCP/IP模型
1. 四层结构
┌─────────────────────────────────┐
│ 应用层 │ HTTP, FTP, SMTP, DNS
├─────────────────────────────────┤
│ 传输层 │ TCP, UDP
├─────────────────────────────────┤
│ 网际层 │ IP, ICMP, IGMP
├─────────────────────────────────┤
│ 网络接口层 │ 以太网, WiFi
└─────────────────────────────────┘
2. OSI与TCP/IP对比
- OSI是理论模型,TCP/IP是事实标准
- OSI七层对应TCP/IP四层的映射关系
- TCP/IP将OSI的上三层合并为应用层
- TCP/IP将OSI的底两层合并为网络接口层
3. Java结合
- Java网络API基于TCP/IP模型设计
java.net包对应应用层和传输层- 理解为什么Java不需要物理层和数据链路层API
周四:协议与服务
1. 协议与服务
- 协议:水平方向,对等层之间的通信规则
- 服务:垂直方向,下层为上层提供功能
- 服务访问点SAP(Service Access Point):层与层交换信息的接口
2. 协议栈
- 协议栈的概念:一组协议的集合
- TCP/IP协议栈:应用层协议+传输层协议+网络层协议
3. Java结合
- Spring MVC处理HTTP协议栈的示意
HTTP请求 → Tomcat Connector → Servlet容器 → Spring Dispatcher → Controller
周五-周六:实践练习
Wireshark抓包实践步骤
- 下载安装Wireshark
- 选择网络接口(通常是以太网或WiFi)
- 设置过滤器:
http或tcp.port == 8080 - 运行Java程序发送HTTP请求
- 分析抓到的数据包
Java代码示例
// 简单的HTTP客户端
import java.net.*;
import java.io.*;
public class SimpleHttpClient {
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
Java实践任务
1. 编写简单的Socket客户端
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
out.println("Hello, Server!");
System.out.println("Server response: " + in.readLine());
socket.close();
}
}
2. 使用Wireshark观察TCP三次握手过程
- 启动抓包
- 运行Socket客户端
- 找到TCP的三次握手报文:SYN → SYN-ACK → ACK
3. 绘制分层模型思维导图
推荐代码实践
- 使用
java.net.Socket实现简单的Echo客户端 - 使用
java.net.HttpURLConnection访问REST API - 使用Wireshark分析上述程序产生的网络流量
第2周:物理层与数据链路层基础
学习目标
- 了解物理层的基本概念
- 掌握数据链路层的帧结构
- 理解MAC地址与ARP协议
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | 物理层概述 | 信号、编码、传输介质 | 理解网络硬件对Java性能的影响 |
| 周二 | 数据链路层 | 帧、差错控制 | 理解MTU对Java传输的影响 |
| 周三 | MAC地址 | 地址格式、交换机工作原理 | 理解服务器多网卡配置 |
| 周四 | ARP协议 | 地址解析过程、ARP缓存 | 理解Java网络编程中的ARP问题 |
| 周五 | 实践练习1 | 查看本机ARP表 | 使用Java获取网络接口信息 |
| 周六 | 实践练习2 | 分析以太网帧 | Wireshark分析帧结构 |
| 周日 | 总结复习 | 整理笔记 | 总结底层协议对上层应用的影响 |
详细学习内容
周一:物理层概述
1. 物理层基本概念
- 物理层的主要任务:确定与传输媒体的接口特性
- 机械特性:接口形状、尺寸、引脚数目
- 电气特性:电压范围、数据传输速率
- 功能特性:各条信号线的用途
- 规程特性:信号线的工作顺序
2. 数据通信基础
- 数据与信号的关系
- 模拟信号与数字信号
- 编码与调制:基带传输、频带传输
3. 传输介质
- 导引型传输介质:双绞线、同轴电缆、光纤
- 非导引型传输介质:无线电波、微波、红外线
4. Java结合
- 网络硬件选择对Java应用性能的影响
- 光纤 vs 双绞线的延迟差异对RPC调用的意义
- 理解为什么数据中心使用光纤
周二:数据链路层
1. 数据链路层基本概念
- 链路:从一个节点到相邻节点的一段物理线路
- 数据链路:链路+协议
- 三个基本问题:封装成帧、透明传输、差错检测
2. 帧结构
- 帧头和帧尾的标识
- 最大传输单元MTU(Maximum Transmission Unit)
- 以太网帧格式
┌─────┬─────┬─────────────┬─────┬─────┐
│前导 │ 目的 │ 源地址 │数据 │ FCS │
│码 │ 地址 │ │ │ │
└─────┴─────┴─────────────┴─────┴─────┘
3. 差错控制
- 奇偶校验
- 循环冗余检验CRC(Cyclic Redundancy Check)
- 纠错编码概念
4. Java结合
- MTU对Java大数据传输的影响
- 当传输数据超过MTU时,IP层会进行分片
- Java Socket缓冲区大小设置
socket.setSendBufferSize(64 * 1024); // 发送缓冲区
socket.setReceiveBufferSize(64 * 1024); // 接收缓冲区
周三:MAC地址
1. MAC地址详解
- MAC地址(Media Access Control Address):48位
- 前24位:厂商识别码(OUI)
- 后24位:厂商分配的网卡编号
- 格式:XX:XX:XX:XX:XX:XX 或 XX-XX-XX-XX-XX-XX
2. MAC地址与IP地址的区别
- MAC地址:二层地址,物理地址,固定不变
- IP地址:三层地址,逻辑地址,可变
- ARP协议负责两者之间的映射
3. 交换机工作原理
- 交换机自学习算法
- MAC地址表
- 广播与单播
- VLAN(虚拟局域网)
4. Java结合
- 使用Java获取本机MAC地址
import java.net.*;
import java.util.*;
public class GetMacAddress {
public static void main(String[] args) throws Exception {
Enumeration<NetworkInterface> interfaces =
NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
byte[] mac = ni.getHardwareAddress();
if (mac != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s",
mac[i], (i < mac.length - 1) ? ":" : ""));
}
System.out.println(ni.getName() + ": " + sb);
}
}
}
}
周四:ARP协议
1. ARP协议详解
- ARP(Address Resolution Protocol):地址解析协议
- 作用:将IP地址解析为MAC地址
- 工作在网络层和数据链路层之间
2. ARP工作流程
1. 主机A想要向主机B发送数据
2. A知道B的IP地址,但不知道B的MAC地址
3. A广播ARP请求:谁有IP地址192.168.1.100?
4. B收到请求,单播ARP应答:我是,MAC地址是aa:bb:cc:dd:ee:ff
5. A将B的IP-MAC映射存入ARP缓存
3. ARP缓存
- ARP表:IP地址到MAC地址的映射表
- 查看ARP表:Windows用
arp -a,Linux用arp -n - ARP表项有超时时间(通常20分钟)
4. ARP欺骗
- ARP欺骗原理
- 中间人攻击
- 防御方法
5. Java结合
- Java无法直接发送ARP包(需要原始套接字)
- 使用Runtime.exec调用系统命令获取ARP表
- 理解为什么Java应用需要关注ARP问题(如网络不通)
周五-周六:实践练习
实践1:查看本机网络接口和ARP表
import java.net.*;
import java.io.*;
public class NetworkInfo {
public static void main(String[] args) throws Exception {
// 获取所有网络接口
System.out.println("=== 网络接口信息 ===");
Enumeration<NetworkInterface> interfaces =
NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
System.out.println("\n接口名: " + ni.getName());
System.out.println("显示名: " + ni.getDisplayName());
System.out.println("MAC地址: " + getMacAddress(ni));
Enumeration<InetAddress> addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
System.out.println("IP地址: " + addr.getHostAddress());
}
}
// 获取ARP表
System.out.println("\n=== ARP表 ===");
Process process = Runtime.getRuntime().exec("arp -a");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
private static String getMacAddress(NetworkInterface ni) {
try {
byte[] mac = ni.getHardwareAddress();
if (mac == null) return "N/A";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i],
(i < mac.length - 1) ? ":" : ""));
}
return sb.toString();
} catch (Exception e) {
return "Error";
}
}
}
实践2:分析以太网帧
- 使用Wireshark抓包
- 查看以太网帧结构
- 分析MAC地址字段
- 观察ARP协议报文
Java实践任务
- 使用NetworkInterface获取本机网络信息
- 理解InetAddress与MAC地址的关系
- 分析以太网MTU对大数据传输的影响
第二阶段:网络层核心(第3-5周)
第3周:IP协议详解
学习目标
- 深入理解IP协议的工作原理
- 掌握IP地址分类与子网划分
- 理解IP路由与转发过程
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | IP协议概述 | IP数据报格式、版本差异 | 理解IPv4与IPv6在Java中的支持 |
| 周二 | IP地址 | 分类、特殊地址、私有地址 | 理解服务器内网/外网IP配置 |
| 周三 | 子网划分 | VLSM、CIDR | 理解Docker网络配置中的子网概念 |
| 周四 | IP路由 | 路由表、路由选择协议 | 理解微服务中的服务发现与路由 |
| 周五 | 实践练习1 | 配置静态路由 | 在本地测试网络路由 |
| 周六 | 实践练习2 | IP分片与重组 | 使用Java发送大数据包观察分片 |
| 周日 | 总结复习 | 整理笔记 | 总结IP协议在分布式系统中的应用 |
详细学习内容
周一:IP协议概述
1. IP协议的作用
- IP(Internet Protocol):网际协议
- 工作在网络层,提供不可靠、无连接的数据报传输
- TCP/IP协议栈的核心协议
2. IP数据报格式(IPv4)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL | DSCP |ECN| 总长度 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 标识符 |标志| 片偏移 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 生存时间 | 协议 | 头部校验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源IP地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 目的IP地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3. IPv4 vs IPv6
| 特性 | IPv4 | IPv6 |
|---|---|---|
| 地址长度 | 32位 | 128位 |
| 地址空间 | 约43亿 | 几乎无限 |
| 头部格式 | 可变长度 | 固定长度 |
| 安全性 | 无(IPSec可选) | 内置IPSec |
| 配置 | 手动或DHCP | 自动配置 |
4. Java结合
// Java对IPv4和IPv6的支持
import java.net.*;
public class IPAddressTest {
public static void main(String[] args) throws Exception {
// IPv4地址
InetAddress ipv4 = InetAddress.getByName("192.168.1.1");
System.out.println("IPv4: " + ipv4.getHostAddress());
System.out.println("Is IPv4? " + (ipv4 instanceof Inet4Address));
// IPv6地址
InetAddress ipv6 = InetAddress.getByName("::1");
System.out.println("IPv6: " + ipv6.getHostAddress());
System.out.println("Is IPv6? " + (ipv6 instanceof Inet6Address));
}
}
周二:IP地址
1. IP地址分类(IPv4)
- A类地址:1.0.0.0 - 126.255.255.255,大型网络
- B类地址:128.0.0.0 - 191.255.255.255,中型网络
- C类地址:192.0.0.0 - 223.255.255.255,小型网络
- D类地址:224.0.0.0 - 239.255.255.255,组播地址
- E类地址:240.0.0.0 - 255.255.255.255,保留地址
2. 特殊IP地址
- 0.0.0.0:当前主机
- 127.0.0.1:本地回环地址
- 255.255.255.255:本地广播地址
- 私有地址:
- A类:10.0.0.0 - 10.255.255.255
- B类:172.16.0.0 - 172.31.255.255
- C类:192.168.0.0 - 192.168.255.255
3. 公网IP与内网IP
- 公网IP:全球唯一,可直接访问
- 内网IP:私有地址,通过NAT访问外网
- 公司服务器通常有内网IP和外网IP
4. Java结合
// 判断内网/外网IP
public class IPLocalCheck {
public static boolean isPrivateIP(String ip) {
String[] privateRanges = {
"10.", "192.168.",
"172.16.", "172.17.", "172.18.", "172.19.",
"172.20.", "172.21.", "172.22.", "172.23.",
"172.24.", "172.25.", "172.26.", "172.27.",
"172.28.", "172.29.", "172.30.", "172.31."
};
for (String range : privateRanges) {
if (ip.startsWith(range)) return true;
}
return ip.equals("127.0.0.1") || ip.equals("localhost");
}
}
周三:子网划分
1. 子网划分基础
- 为什么要划分子网:提高IP地址利用率,隔离网络流量
- 子网掩码:区分网络部分和主机部分
- 网络地址、主机地址、广播地址
2. CIDR(无类域间路由)
- 表示法:192.168.1.0/24
- /24表示前24位是网络部分
- VLSM(可变长子网掩码)
3. 子网划分计算示例
- 网络地址:192.168.1.0/24
- 子网掩码:255.255.255.0
- 可用主机数:2^8 - 2 = 254
- 分成4个子网:/26 → 每个子网62个主机
4. Docker网络中的子网
# Docker默认创建的bridge网络
docker network inspect bridge
# 输出中的Subnet: 172.17.0.0/16
# 创建自定义网络
docker network create --subnet=192.168.100.0/24 mynet
周四:IP路由
1. 路由基本概念
- 路由:从源到目的地的路径选择
- 路由器:工作在网络层,转发数据包
- 路由表:记录到达目的网络的路径
2. 路由表结构
目的网络 子网掩码 网关 接口
0.0.0.0 0.0.0.0 192.168.1.1 eth0(默认路由)
192.168.1.0 255.255.255.0 0.0.0.0 eth0(直连网络)
10.0.0.0 255.0.0.0 192.168.1.254 eth0(静态路由)
3. 路由选择协议
- 内部网关协议:RIP、OSPF
- 外部网关协议:BGP
- 静态路由 vs 动态路由
4. 微服务中的服务发现与路由
- 服务注册中心:Nacos、Eureka、Consul
- 客户端负载均衡:Ribbon、LoadBalancer
- 服务端负载均衡:Nginx、网关
- 网关路由:Spring Cloud Gateway、Zuul
5. Java结合
# Spring Cloud Gateway路由配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
周五-周六:实践练习
实践1:查看和配置路由
# Windows查看路由表
route print
# Linux查看路由表
route -n
# 或
ip route show
# 添加静态路由
route add 10.0.0.0 mask 255.0.0.0 192.168.1.254
实践2:IP分片与重组
import java.net.*;
import java.io.*;
public class IPFragmentation {
public static void main(String[] args) throws Exception {
// 发送大于MTU的数据,观察IP分片
Socket socket = new Socket("example.com", 80);
socket.setSendBufferSize(16 * 1024); // 设置发送缓冲区
OutputStream out = socket.getOutputStream();
// 发送大于MTU的数据
byte[] largeData = new byte[10000]; // 10KB
out.write(largeData);
socket.close();
}
}
// 使用Wireshark观察IP分片:
// 1. 设置过滤器:ip.fragments
// 2. 观察分片包的标识、偏移量、标志位
Java实践任务
- 使用InetAddress处理IPv4和IPv6
- 编写简单的路由追踪程序(类似traceroute)
- 理解Spring Cloud Gateway中的路由原理
第4周:ICMP、ping与网络诊断
学习目标
- 掌握ICMP协议的工作机制
- 学会使用网络诊断工具
- 理解网络故障排查方法
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | ICMP协议 | 报文格式、类型与代码 | 理解Java中实现ping的原理 |
| 周二 | Ping工具 | ICMP回显请求与应答 | 使用Java实现ping功能 |
| 周三 | Traceroute | TTL机制、路由追踪 | 使用Java实现traceroute |
| 周四 | 网络故障排查 | 常见问题与诊断方法 | 理解微服务中的网络问题诊断 |
| 周五 | 实践练习1 | 使用ping诊断网络 | 编写Java网络诊断工具 |
| 周六 | 实践练习2 | 使用traceroute追踪路由 | 分析网络延迟与丢包 |
| 周日 | 总结复习 | 整理笔记 | 总结网络诊断在运维中的应用 |
详细学习内容
周一:ICMP协议
1. ICMP协议概述
- ICMP(Internet Control Message Protocol):网际控制报文协议
- 工作在网络层,用于传递差错报文和控制信息
- 是IP协议的一部分,不是独立协议
2. ICMP报文格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 类型 | 代码 | 校验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 取决于ICMP报文类型 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3. ICMP报文类型
- 差错报告报文
- 类型3:终点不可达
- 类型4:源站抑制
- 类型5:重定向
- 类型11:时间超过
- 查询报文
- 类型8:回显请求(Echo Request)
- 类型0:回显应答(Echo Reply)
- 类型13:时间戳请求
- 类型14:时间戳应答
4. Java结合
- Java标准库不直接支持ICMP(需要原始套接字)
- 使用
InetAddress.isReachable()方法 - 理解为什么ping需要管理员权限
周二:Ping工具
1. Ping工作原理
1. 源主机发送ICMP回显请求(Type=8)
2. 目的主机返回ICMP回显应答(Type=0)
3. 源主机计算RTT(往返时间)
2. Ping命令详解
ping 192.168.1.1
# 输出解释:
# 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.5 ms
# 64 bytes: 回显应答的数据大小
# icmp_seq=1: 序列号
# ttl=64: 生存时间
# time=0.5 ms: 往返时间
3. Ping的用途
- 检测网络连通性
- 测量网络延迟
- 诊断网络故障
- DNS解析测试
4. Java实现Ping
import java.net.*;
import java.io.*;
public class PingTool {
public static void main(String[] args) {
String host = "www.baidu.com";
ping(host);
}
public static void ping(String host) {
try {
InetAddress address = InetAddress.getByName(host);
System.out.println("Pinging " + host + " [" + address.getHostAddress() + "]:");
long startTime = System.currentTimeMillis();
boolean reachable = address.isReachable(5000); // 5秒超时
long endTime = System.currentTimeMillis();
if (reachable) {
System.out.println("Reply from " + address.getHostAddress() +
": time=" + (endTime - startTime) + "ms");
} else {
System.out.println("Request timed out.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 注意:isReachable()在Windows上可能不准确
// 可以使用Runtime.exec调用系统ping命令
周三:Traceroute
1. Traceroute工作原理
- 利用IP数据报中的TTL(Time To Live)字段
- TTL每经过一个路由器减1
- 当TTL=0时,路由器返回ICMP时间超过报文
步骤1:发送TTL=1的包 → 第一个路由器返回ICMP超时
步骤2:发送TTL=2的包 → 第二个路由器返回ICMP超时
...
步骤N:发送TTL=N的包 → 目标主机返回ICMP回显应答
2. Traceroute命令
# Windows
tracert www.baidu.com
# Linux/Mac
traceroute www.baidu.com
周四:网络故障排查
1. 常见网络问题
- 物理连接问题:网线松动、接口损坏
- IP配置问题:IP冲突、子网掩码错误
- 路由问题:网关配置错误、路由缺失
- DNS问题:域名解析失败
- 防火墙问题:端口被阻止
2. 诊断步骤
步骤1:ping 127.0.0.1 - 检查TCP/IP协议栈
步骤2:ping 本机IP - 检查网卡
步骤3:ping 网关 - 检查本地网络
步骤4:ping 公网IP - 检查外网连接
步骤5:ping 域名 - 检查DNS
3. 微服务网络诊断
- 服务健康检查:Spring Boot Actuator
- 服务间连通性:Feign超时配置
- 链路追踪:SkyWalking、Zipkin
- 日志分析:ELK Stack
4. Java结合
// Spring Boot Actuator健康检查
@Component
public class NetworkHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
InetAddress addr = InetAddress.getByName("database-server");
if (addr.isReachable(3000)) {
return Health.up()
.withDetail("server", "database-server")
.build();
}
} catch (IOException e) {
return Health.down()
.withDetail("error", e.getMessage())
.build();
}
return Health.down().build();
}
}
周五-周六:实践练习
综合网络诊断工具
import java.net.*;
import java.io.*;
public class NetworkDiagnostic {
public static void main(String[] args) {
String target = "www.baidu.com";
System.out.println("=== 网络诊断工具 ===");
System.out.println("目标: " + target + "\n");
// 1. DNS解析测试
System.out.println("[1] DNS解析测试");
testDNS(target);
// 2. Ping测试
System.out.println("\n[2] Ping测试");
ping(target);
// 3. 端口连通性测试
System.out.println("\n[3] 端口连通性测试");
testPort(target, 80);
testPort(target, 443);
// 4. 本机网络信息
System.out.println("\n[4] 本机网络信息");
showLocalNetworkInfo();
}
public static void testDNS(String host) {
try {
InetAddress addr = InetAddress.getByName(host);
System.out.println("✓ DNS解析成功");
System.out.println(" 域名: " + host);
System.out.println(" IP: " + addr.getHostAddress());
} catch (UnknownHostException e) {
System.out.println("✗ DNS解析失败: " + e.getMessage());
}
}
public static void ping(String host) {
try {
InetAddress addr = InetAddress.getByName(host);
long total = 0;
int success = 0;
for (int i = 0; i < 4; i++) {
long start = System.currentTimeMillis();
boolean reachable = addr.isReachable(3000);
long time = System.currentTimeMillis() - start;
if (reachable) {
System.out.println(" 回复来自 " + addr.getHostAddress() +
": 时间=" + time + "ms");
total += time;
success++;
} else {
System.out.println(" 请求超时");
}
}
if (success > 0) {
System.out.println(" " + host + " 的 Ping 统计信息:");
System.out.println(" 数据包: 已发送 = 4,已接收 = " +
success + ",丢失 = " + (4 - success));
System.out.println(" 平均往返时间: " + (total / success) + "ms");
}
} catch (Exception e) {
System.out.println("✗ Ping失败: " + e.getMessage());
}
}
public static void testPort(String host, int port) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), 3000);
System.out.println(" 端口 " + port + ": 开放");
} catch (Exception e) {
System.out.println(" 端口 " + port + ": 关闭或不可达");
}
}
public static void showLocalNetworkInfo() {
try {
System.out.println(" 主机名: " + InetAddress.getLocalHost().getHostName());
Enumeration<NetworkInterface> interfaces =
NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
if (ni.isUp()) {
System.out.println("\n 接口: " + ni.getDisplayName());
Enumeration<InetAddress> addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address) {
System.out.println(" IPv4: " + addr.getHostAddress());
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java实践任务
- 使用Java实现ICMP ping(需要管理员权限)
- 实现简单的网络连通性检测工具
- 集成到Spring Boot Actuator健康检查中
第5周:NAT、VPN与网络安全基础
学习目标
- 理解NAT的工作原理与应用场景
- 了解VPN技术
- 掌握基本的网络安全概念
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | NAT技术 | 工作原理、NAT类型 | 理解公司内网与外网通信 |
| 周二 | NAT穿透 | STUN、TURN、ICE | 理解P2P应用中的NAT问题 |
| 周三 | VPN技术 | 隧道技术、加密 | 理解远程办公的网络配置 |
| 周四 | 网络安全基础 | 防火墙、入侵检测 | 理解Spring Security中的网络安全 |
| 周五 | 实践练习1 | 配置NAT | 在虚拟机中配置NAT网络 |
| 周六 | 实践练习2 | 分析HTTPS流量 | 理解SSL/TLS在网络层的位置 |
| 周日 | 总结复习 | 整理笔记 | 总结网络安全对Java应用的影响 |
详细学习内容
周一:NAT技术
1. NAT概述
- NAT(Network Address Translation):网络地址转换
- 作用:将私有IP地址转换为公网IP地址
- 解决IPv4地址不足问题
2. NAT工作原理
内网主机: 192.168.1.100:8080
↓
NAT路由器: 公网IP 202.1.1.1
转换表: {192.168.1.100:8080 → 202.1.1.1:60001}
↓
外网服务器看到: 202.1.1.1:60001
3. NAT类型
- 静态NAT:一对一固定映射
- 动态NAT:一对一动态映射
- NAPT(端口地址转换):多对一,通过端口区分
- Easy IP:使用接口IP作为公网IP
4. Java结合
- 理解为什么内网服务器无法直接从外网访问
- 反向代理与NAT的关系
- 获取真实客户端IP的问题
// 获取客户端真实IP(考虑反向代理)
public class IpUtil {
public static String getRealIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 处理多个IP的情况(X-Forwarded-For: client, proxy1, proxy2)
if (ip != null && ip.contains(",")) {
ip = ip.split(",")[0].trim();
}
return ip;
}
}
周二:NAT穿透
1. NAT穿透场景
- P2P应用:两个内网主机直连
- VoIP:语音视频通话
- 在线游戏:玩家之间直连
2. NAT类型
- 完全圆锥型NAT(Full Cone)
- 受限圆锥型NAT(Restricted Cone)
- 端口受限圆锥型NAT(Port Restricted Cone)
- 对称型NAT(Symmetric)
3. NAT穿透技术
- STUN(Session Traversal Utilities for NAT)
- TURN(Traversal Using Relays around NAT)
- ICE(Interactive Connectivity Establishment)
周三:VPN技术
1. VPN概述
- VPN(Virtual Private Network):虚拟专用网络
- 在公网上建立专用的加密通道
- 应用场景:远程办公、分支机构互联
2. VPN技术
- 隧道技术:封装协议
- 加密技术:保证数据安全
- 身份认证:验证用户身份
3. VPN协议
- PPTP:较老,安全性较低
- L2TP/IPsec:常用,安全性较好
- OpenVPN:开源,安全性高
- WireGuard:新一代VPN协议,性能优秀
- SSL VPN:基于HTTPS,无需客户端
4. 远程办公网络架构
居家电脑 ---VPN---> 公司VPN网关 ---> 内网服务器
周四:网络安全基础
1. 防火墙
- 包过滤防火墙:根据IP、端口过滤
- 应用层防火墙:根据应用层内容过滤
- 状态检测防火墙:跟踪连接状态
2. 常见网络攻击
- DDoS攻击:分布式拒绝服务
- 中间人攻击:拦截通信
- ARP欺骗:伪造MAC地址
- DNS劫持:伪造DNS响应
3. Spring Security网络安全
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 防止CSRF攻击
.csrf(csrf -> csrf.disable())
// 配置CORS
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
// 防止点击劫持
.headers(headers -> headers
.xssProtection(xss -> xss.disable())
.frameOptions(frame -> frame.deny())
)
// 防火墙规则
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasIpAddress("192.168.1.0/24")
.anyRequest().authenticated()
);
return http.build();
}
}
周五-周六:实践练习
实践1:分析NAT行为
# 查看本机的公网IP
curl ifconfig.me
# 在虚拟机中配置NAT网络
# VirtualBox: 设置 -> 网络 -> 网络地址转换(NAT)
# 使用Wireshark分析NAT转换前后IP地址变化
实践2:配置HTTPS
// Spring Boot HTTPS配置
// application.yml
server:
port: 8443
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: changeit
key-store-type: PKCS12
key-alias: tomcat
// 使用Java自带的keytool生成证书
// keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12
Java实践任务
- 理解反向代理后的IP获取问题(X-Forwarded-For)
- 学习SSL/TLS在Java中的配置
- 分析NAT对WebSocket长连接的影响
第三阶段:传输层深入(第6-8周)
第6周:UDP协议
学习目标
- 深入理解UDP协议的特点
- 掌握UDP适用场景
- 学习UDP在Java中的应用
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | UDP协议概述 | 报文格式、特点 | 理解UDP与TCP的选择 |
| 周二 | UDP通信 | 无连接、不可靠 | 使用Java实现UDP通信 |
| 周三 | UDP应用场景 | DNS、视频流、游戏 | 分析高性能场景下的UDP使用 |
| 周四 | UDP增强 | QUIC、WebRTC | 了解现代UDP协议改进 |
| 周五 | 实践练习1 | UDP编程 | 实现UDP聊天室 |
| 周六 | 实践练习2 | UDP vs TCP | 对比测试性能差异 |
| 周日 | 总结复习 | 整理笔记 | 总结UDP在实际项目中的应用 |
详细学习内容
周一:UDP协议概述
1. UDP特点
- 无连接:不需要建立连接
- 不可靠:不保证数据送达
- 面向报文:保持报文边界
- 无拥塞控制:网络拥塞时不降低发送速率
- 头部开销小:仅8字节
2. UDP报文格式
0 7 8 15 16 23 24 31
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口 | 目的端口 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 长度 | 校验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3. UDP vs TCP对比
| 特性 | UDP | TCP |
|---|---|---|
| 连接 | 无连接 | 面向连接 |
| 可靠性 | 不可靠 | 可靠 |
| 顺序 | 不保证 | 保证顺序 |
| 速度 | 快 | 较慢 |
| 头部 | 8字节 | 20-60字节 |
| 应用 | DNS、视频流 | HTTP、FTP |
4. Java UDP API
// UDP相关类
java.net.DatagramSocket // UDP套接字
java.net.DatagramPacket // UDP数据包
java.net.MulticastSocket // 组播套接字
周二:UDP通信
1. UDP服务器
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9876);
byte[] buffer = new byte[1024];
System.out.println("UDP服务器启动,监听端口9876...");
while (true) {
// 接收数据
DatagramPacket receivePacket =
new DatagramPacket(buffer, buffer.length);
socket.receive(receivePacket);
String message = new String(
receivePacket.getData(),
0,
receivePacket.getLength()
);
System.out.println("收到来自 " +
receivePacket.getAddress() + ":" +
receivePacket.getPort() + " 的消息: " + message);
// 发送响应
String response = "已收到: " + message;
byte[] responseData = response.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(
responseData,
responseData.length,
receivePacket.getAddress(),
receivePacket.getPort()
);
socket.send(sendPacket);
}
}
}
2. UDP客户端
import java.net.*;
import java.util.Scanner;
public class UDPClient {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
InetAddress serverAddress = InetAddress.getByName("localhost");
int serverPort = 9876;
System.out.println("已连接到UDP服务器");
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if ("exit".equals(message)) break;
// 发送数据
byte[] sendData = message.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, serverAddress, serverPort);
socket.send(sendPacket);
// 接收响应
byte[] buffer = new byte[1024];
DatagramPacket receivePacket =
new DatagramPacket(buffer, buffer.length);
socket.receive(receivePacket);
String response = new String(
receivePacket.getData(),
0,
receivePacket.getLength()
);
System.out.println("服务器响应: " + response);
}
scanner.close();
socket.close();
}
}
周三:UDP应用场景
1. DNS查询
- DNS使用UDP 53端口
- 查询响应小于512字节时使用UDP
- 大于512字节时使用TCP
2. 视频流媒体
- 实时性要求高
- 允许少量丢包
- RTP(Real-time Transport Protocol)基于UDP
3. 在线游戏
- 低延迟要求
- 状态同步
- 需要应用层实现可靠性
4. 日志收集
- Syslog使用UDP
- 允许日志丢失
- 高吞吐量
周四:UDP增强
1. QUIC协议
- Google开发的基于UDP的传输协议
- HTTP/3使用QUIC
- 特点:
- 多路复用,避免队头阻塞
- 内置TLS 1.3加密
- 连接迁移
- 快速握手
2. WebRTC
- 网页实时通信
- 音视频通话
- 基于UDP的SRTP协议
3. KCP协议
- 快速可靠传输协议
- 比TCP延迟降低30%
- 应用于游戏、直播
周五-周六:实践练习
实践:UDP聊天室
import java.net.*;
import java.util.*;
import java.io.*;
public class UDPChat {
private static final int PORT = 9999;
private static final String MULTICAST_GROUP = "239.255.255.250";
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的昵称: ");
String nickname = scanner.nextLine();
MulticastSocket socket = new MulticastSocket(PORT);
InetAddress group = InetAddress.getByName(MULTICAST_GROUP);
socket.joinGroup(group);
// 接收线程
Thread receiveThread = new Thread(() -> {
try {
byte[] buffer = new byte[1024];
while (true) {
DatagramPacket packet =
new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String message = new String(
packet.getData(),
0,
packet.getLength()
);
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
});
receiveThread.setDaemon(true);
receiveThread.start();
// 发送消息
System.out.println("已加入聊天室,输入消息开始聊天...");
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if ("exit".equals(message)) break;
String fullMessage = nickname + ": " + message;
byte[] data = fullMessage.getBytes();
DatagramPacket packet =
new DatagramPacket(data, data.length, group, PORT);
socket.send(packet);
}
socket.leaveGroup(group);
socket.close();
scanner.close();
}
}
Java实践任务
- 使用DatagramSocket实现UDP通信
- 实现简单的DNS查询客户端
- 对比UDP和TCP在文件传输中的差异
第7周:TCP协议详解(上)
学习目标
- 深入理解TCP协议的核心机制
- 掌握TCP连接建立与终止
- 理解TCP的可靠传输机制
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | TCP协议概述 | 报文格式、特点 | 理解Java Socket的底层实现 |
| 周二 | TCP连接建立 | 三次握手、SYN Flood | 理解TCP连接建立的开销 |
| 周三 | TCP连接终止 | 四次挥手、TIME_WAIT | 理解连接池的设计原因 |
| 周四 | TCP可靠传输 | 序列号、确认应答、重传 | 理解TCP对Java应用的影响 |
| 周五 | 实践练习1 | 分析TCP握手 | Wireshark抓包分析 |
| 周六 | 实践练习2 | TIME_WAIT问题 | 模拟高并发连接场景 |
| 周日 | 总结复习 | 整理笔记 | 总结TCP在Java开发中的重要性 |
详细学习内容
周一:TCP协议概述
1. TCP特点
- 面向连接:需要建立连接
- 可靠传输:保证数据送达
- 面向字节流:无边界
- 全双工通信:双向传输
- 点对点:一对一通信
2. TCP报文格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口 | 目的端口 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 序列号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 确认号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|数据偏移|保留|U|A|P|R|S|F| 窗口 |
| | |R|C|S|Y|I| |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 校验和 | 紧急指针 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项(可选) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3. TCP标志位
- SYN:同步序号,用于建立连接
- ACK:确认号有效
- FIN:结束连接
- RST:重置连接
- PSH:推送数据
- URG:紧急指针有效
4. Java TCP API
// TCP相关类
java.net.Socket // 客户端套接字
java.net.ServerSocket // 服务器套接字
java.net.SocketAddress // 套接字地址
java.net.SocketTimeoutException // 超时异常
周二:TCP连接建立
1. 三次握手过程
客户端 服务器
────────────────────────────────────────────────
CLOSED LISTEN
SYN_SENT, SEQ=0
───────────────────────────────────────────────>
SYN_RCVD
<────────────────────────────────────────────────
SYN, ACK=1, SEQ=0
ESTABLISHED
───────────────────────────────────────────────>
ACK=1, SEQ=1
ESTABLISHED
- 第一次握手:客户端发送SYN,seq=x
- 第二次握手:服务器发送SYN+ACK,seq=y, ack=x+1
- 第三次握手:客户端发送ACK,seq=x+1, ack=y+1
2. 为什么需要三次握手
- 确认双方收发能力都正常
- 防止已失效的连接请求报文
- 同步双方的初始序列号
3. SYN Flood攻击
- 攻击原理:发送大量SYN包,不完成握手
- 后果:耗尽服务器资源
- 防御:SYN Cookie、缩短超时时间
4. Java结合
// TCP连接建立示例
import java.net.*;
public class TCPConnection {
public static void main(String[] args) throws Exception {
// 客户端连接
Socket socket = new Socket();
SocketAddress endpoint = new InetSocketAddress("localhost", 8080);
// 设置连接超时
socket.connect(endpoint, 5000); // 5秒超时
// 设置Socket选项
socket.setTcpNoDelay(true); // 禁用Nagle算法
socket.setKeepAlive(true); // 保持连接
socket.setSoTimeout(30000); // 读取超时30秒
System.out.println("已连接到服务器");
socket.close();
}
}
周三:TCP连接终止
1. 四次挥手过程
主动方 被动方
────────────────────────────────────────────────
ESTABLISHED ESTABLISHED
FIN-WAIT-1, SEQ=x
───────────────────────────────────────────────>
───────────────────────────────────────────────>
ACK=x+1, SEQ=y, CLOSE-WAIT
FIN-WAIT-2
───────────────────────────────────────────────>
FIN, ACK=x+1, SEQ=y, LAST-ACK
<────────────────────────────────────────────────
TIME-WAIT
───────────────────────────────────────────────>
ACK=y+1, SEQ=x+1
CLOSED CLOSED
2. TIME_WAIT状态
- 持续时间:2MSL(Maximum Segment Lifetime,约60秒)
- 作用:
- 确保最后的ACK能到达对方
- 确保旧连接的报文自然消失
3. TIME_WAIT问题
- 高并发场景下端口耗尽
- 解决方案:
- 启用SO_REUSEADDR
- 调整操作系统参数
- 使用连接池
4. Java结合
// ServerSocket配置
ServerSocket serverSocket = new ServerSocket(8080);
serverSocket.setReuseAddress(true); // 允许重用地址
周四:TCP可靠传输
1. 序列号与确认应答
- 序列号:标识数据字节序号
- 确认号:期望收到的下一个字节
- 累积确认:确认号之前的所有字节都已收到
2. 超时重传
- RTO(Retransmission Timeout):重传超时时间
- 动态调整:根据RTT计算
- 快速重传:收到3个重复ACK立即重传
3. 滑动窗口
- 窗口大小:接收缓冲区剩余空间
- 滑动窗口协议:控制发送速率
- 零窗口问题:窗口通告为0
4. Java结合
// 设置发送和接收缓冲区
Socket socket = new Socket("localhost", 8080);
socket.setSendBufferSize(64 * 1024); // 发送缓冲区64KB
socket.setReceiveBufferSize(64 * 1024); // 接收缓冲区64KB
// 查看实际缓冲区大小
System.out.println("发送缓冲区: " + socket.getSendBufferSize());
System.out.println("接收缓冲区: " + socket.getReceiveBufferSize());
周五-周六:实践练习
实践1:分析TCP握手
# 使用Wireshark抓包
# 过滤器:tcp.flags.syn==1
# 观察TCP三次握手
# 1. SYN包:Flags=0x002 (SYN)
# 2. SYN-ACK包:Flags=0x012 (SYN, ACK)
# 3. ACK包:Flags=0x010 (ACK)
实践2:TIME_WAIT问题演示
import java.net.*;
import java.io.*;
public class TimeWaitDemo {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100; i++) {
Socket socket = null;
try {
socket = new Socket("www.baidu.com", 80);
socket.setSoLinger(true, 0); // 立即关闭,进入TIME_WAIT
System.out.println("连接 " + i + " 建立");
} finally {
if (socket != null) {
socket.close();
}
}
}
}
}
// 使用netstat观察TIME_WAIT状态
// Windows: netstat -ano | findstr TIME_WAIT
// Linux: ss -tan | grep TIME_WAIT
Java实践任务
- 使用Socket建立TCP连接
- 设置Socket选项分析TCP行为
- 理解HTTP连接复用(Keep-Alive)
第8周:TCP协议详解(下)
学习目标
- 掌握TCP流量控制与拥塞控制
- 理解TCP粘包拆包问题
- 学习TCP调优参数
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | TCP流量控制 | 滑动窗口、窗口通告 | 理解Socket缓冲区配置 |
| 周二 | TCP拥塞控制 | 慢启动、拥塞避免 | 理解网络拥塞对应用的影响 |
| 周三 | TCP粘包拆包 | 问题现象、解决方案 | 使用Netty解决粘包问题 |
| 周四 | TCP调优 | 参数优化、性能调优 | Java应用的TCP参数调优 |
| 周五 | 实践练习1 | 粘包拆包演示 | 编写演示代码 |
| 周六 | 实践练习2 | TCP性能测试 | 使用JMeter进行压力测试 |
| 周日 | 总结复习 | 整理笔记 | 总结TCP调优实战经验 |
详细学习内容
周一:TCP流量控制
1. 滑动窗口机制
发送方:
┌─────────────────────────────────────────────┐
│ 已发送已确认 │ 已发送未确认 │ 未发送 │
│ │ 窗口 │ │
└─────────────────────────────────────────────┘
↑ ↑
窗口左沿 窗口右沿
2. 窗口通告
- TCP头部的窗口大小字段
- 告诉对方接收缓冲区的剩余空间
- 窗口为0时停止发送
3. 窗口缩放选项
- 窗口大小字段只有16位,最大65535字节
- 窗口缩放选项将窗口扩大2^S倍
- 在高带宽延迟网络中很重要
4. Java结合
// 配置接收缓冲区
Socket socket = new Socket("localhost", 8080);
socket.setReceiveBufferSize(128 * 1024); // 128KB接收缓冲区
// ServerSocket配置
ServerSocket serverSocket = new ServerSocket(8080);
serverSocket.setReceiveBufferSize(128 * 1024);
周二:TCP拥塞控制
1. 拥塞控制算法
慢启动阶段:
┌─────────────────────────────────────────────┐
│ cwnd = 1, 2, 4, 8, 16 ... 指数增长 │
└─────────────────────────────────────────────┘
拥塞避免阶段:
┌─────────────────────────────────────────────┐
│ cwnd 线性增长 │
└─────────────────────────────────────────────┘
快重传与快恢复:
┌─────────────────────────────────────────────┐
│ 收到3个重复ACK → 快重传 │
│ cwnd = ssthreshold + 3 │
└─────────────────────────────────────────────┘
2. 拥塞窗口与接收窗口
- 拥塞窗口:发送方根据网络状况
- 发送窗口 = min(拥塞窗口, 接收窗口)
周三:TCP粘包拆包
1. 问题现象
发送方发送:
[包1: ABC] [包2: DEF] [包3: GHI]
接收方可能收到:
情况1(正常):[ABC] [DEF] [GHI]
情况2(粘包):[ABCDEF] [GHI]
情况3(拆包):[AB] [CDEF] [GHI]
情况4(粘+拆):[ABCD] [EFGHI]
2. 原因分析
- TCP是字节流协议,无消息边界
- 发送方的Nagle算法
- 接收方的缓冲区大小
- 网络MTU限制
3. 解决方案
- 固定长度:每个包固定大小
- 分隔符:使用特殊字符分隔
- 长度字段:包头部携带长度信息
- Netty提供的解码器
4. Netty解决粘包问题
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class NettyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
// 解决粘包拆包问题
// 长度字段解码器:4字节长度,长度字段之后
pipeline.addLast(new LengthFieldBasedFrameDecoder(
Integer.MAX_VALUE, // 最大帧长度
0, // 长度字段偏移量
4, // 长度字段长度
0, // 长度调整值
4 // 初始跳过的字节数
));
// 长度字段编码器:在数据前添加4字节长度
pipeline.addLast(new LengthFieldPrepender(4));
// 字符串编解码
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
// 业务处理器
pipeline.addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx,
String msg) {
System.out.println("收到: " + msg);
ctx.writeAndFlush("已收到: " + msg);
}
});
}
});
ChannelFuture future = bootstrap.bind(8080).sync();
System.out.println("Netty服务器启动成功,监听端口8080");
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
周四:TCP调优
1. 系统级调优
# Linux TCP参数调优
# /etc/sysctl.conf
# TCP连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
# TIME_WAIT优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# TCP缓冲区
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP保活
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# 应用配置
sysctl -p
2. Java应用调优
// Tomcat Connector配置
// server.xml
<Connector port="8080"
protocol="HTTP/1.1"
maxThreads="800"
acceptCount="1000"
connectionTimeout="30000"
socket.soKeepAlive="true"
socket.soTimeout="10000"
socket.tcpNoDelay="true"
socket.rxBufSize="32768"
socket.txBufSize="32768" />
// Netty参数调优
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.option(ChannelOption.SO_BACKLOG, 1024) // 连接队列
.option(ChannelOption.SO_REUSEADDR, true) // 重用地址
.childOption(ChannelOption.SO_KEEPALIVE, true) // 保活
.childOption(ChannelOption.TCP_NODELAY, true) // 禁用Nagle
.childOption(ChannelOption.SO_SNDBUF, 32 * 1024) // 发送缓冲区
.childOption(ChannelOption.SO_RCVBUF, 32 * 1024); // 接收缓冲区
3. HTTP连接池调优
// OkHttp连接池配置
OkHttpClient client = new OkHttpClient.Builder()
.connectionPool(new ConnectionPool(
20, // 最大空闲连接数
5, // 保持时间(分钟)
TimeUnit.MINUTES
))
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
周五-周六:实践练习
实践1:粘包拆包演示
import java.net.*;
import java.io.*;
public class TCPStickyPacketDemo {
// 服务器
static class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
byte[] buffer = new byte[1024];
int total = 0;
while (true) {
int len = in.read(buffer);
if (len == -1) break;
total += len;
System.out.println("收到 " + len + " 字节: " +
new String(buffer, 0, len));
}
System.out.println("总共收到: " + total + " 字节");
}
}
// 客户端
static class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 9999);
OutputStream out = socket.getOutputStream();
// 连续发送多个小包
for (int i = 0; i < 100; i++) {
String msg = "消息" + i;
out.write(msg.getBytes());
// 不flush,观察粘包现象
}
out.flush();
socket.close();
}
}
}
Java实践任务
- 使用Netty解决TCP粘包问题
- 配置Socket参数优化性能
- 理解Netty中的ByteBuf与TCP数据传输
第四阶段:应用层协议(第9-11周)
第9周:HTTP/HTTPS协议
学习目标
- 深入理解HTTP/1.1、HTTP/2协议
- 掌握HTTPS加密机制
- 学习HTTP在Java中的最佳实践
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | HTTP基础 | 请求方法、状态码、头部 | 理解Spring MVC的HTTP处理 |
| 周二 | HTTP特性 | 缓存、Cookie、Session | 理解Session共享问题 |
| 周三 | HTTP/1.1优化 | Keep-Alive、管线化 | 理解HTTP连接池 |
| 周四 | HTTP/2 | 多路复用、头部压缩 | 理解Netty对HTTP/2的支持 |
| 周五 | HTTPS | SSL/TLS、证书链 | 配置Spring Boot的HTTPS |
| 周六 | 实践练习 | HTTP性能对比 | 测试不同HTTP版本性能 |
| 周日 | 总结复习 | 整理笔记 | 总结HTTP优化实战经验 |
详细学习内容
周一:HTTP基础
1. HTTP请求方法
| 方法 | 描述 | 幂等性 | 安全性 |
|---|---|---|---|
| GET | 获取资源 | ✓ | ✓ |
| POST | 创建资源 | ✗ | ✗ |
| PUT | 更新资源 | ✓ | ✗ |
| DELETE | 删除资源 | ✓ | ✗ |
| PATCH | 部分更新 | ✗ | ✗ |
| HEAD | 获取头部 | ✓ | ✓ |
| OPTIONS | 获取支持的方法 | ✓ | ✓ |
2. HTTP状态码
1xx:信息性
100 Continue
101 Switching Protocols
2xx:成功
200 OK
201 Created
204 No Content
3xx:重定向
301 Moved Permanently(永久重定向)
302 Found(临时重定向)
304 Not Modified
4xx:客户端错误
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
409 Conflict
429 Too Many Requests
5xx:服务器错误
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
3. Spring MVC处理HTTP请求
@RestController
@RequestMapping("/api/users")
public class UserController {
// GET请求
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
// POST请求
@PostMapping
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User created = userService.create(user);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
// PUT请求
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id,
@RequestBody User user) {
User updated = userService.update(id, user);
return ResponseEntity.ok(updated);
}
// DELETE请求
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
// 处理不同Content-Type
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {
return ResponseEntity.ok("File uploaded: " + file.getOriginalFilename());
}
}
周二:HTTP缓存、Cookie与Session
1. HTTP缓存机制
强缓存:
Cache-Control: max-age=3600
Expires: Wed, 21 Oct 2025 07:28:00 GMT
协商缓存:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
请求头:
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
2. Spring Boot缓存配置
@RestController
@CacheConfig(cacheNames = "users")
public class UserCacheController {
@GetMapping("/{id}")
@Cacheable(key = "#id")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PutMapping("/{id}")
@CachePut(key = "#id")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
return userService.update(id, user);
}
@DeleteMapping("/{id}")
@CacheEvict(key = "#id")
public void deleteUser(@PathVariable Long id) {
userService.delete(id);
}
}
周三:HTTP/1.1优化
1. 持久连接(Keep-Alive)
请求头:Connection: keep-alive
响应头:Connection: keep-alive
Keep-Alive: timeout=5, max=1000
2. HTTP连接池
// Apache HttpClient连接池
@Configuration
public class HttpClientConfig {
@Bean
public CloseableHttpClient httpClient() {
PoolingHttpClientConnectionManager connectionManager =
PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnTotal(200) // 最大连接数
.setMaxConnPerRoute(50) // 每个路由最大连接数
.build();
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(30000)
.build())
.build();
}
}
周四:HTTP/2
1. HTTP/2特性
- 二进制协议:不再是文本协议
- 多路复用:一个连接并发多个请求
- 头部压缩:HPACK算法
- 服务器推送:主动推送资源
- 流优先级:控制资源加载顺序
周五:HTTPS
1. SSL/TLS握手过程
客户端 服务器
────────────────────────────────────────────────────────
ClientHello
───────────────────────────────────────────────────────────>
ServerHello
Certificate
ServerKeyExchange
CertificateRequest
ServerHelloDone
<────────────────────────────────────────────────────────────
Certificate
ClientKeyExchange
CertificateVerify
ChangeCipherSpec
Finished
───────────────────────────────────────────────────────────>
ChangeCipherSpec
Finished
<────────────────────────────────────────────────────────────
2. Spring Boot HTTPS配置
# application.yml
server:
port: 8443
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: changeit
key-store-type: PKCS12
key-alias: tomcat
protocol: TLSv1.3
Java实践任务
- 使用OkHttp发起HTTP/2请求
- 配置Spring Boot启用HTTPS
- 实现HTTP缓存机制
第10周:应用层协议专题
学习目标
- 掌握DNS、WebSocket、gRPC等协议
- 理解各协议的适用场景
- 学习在Java中实现这些协议
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | DNS协议 | 域名解析、DNS缓存 | 理解服务发现问题 |
| 周二 | WebSocket协议 | 握手、帧格式 | 实现WebSocket推送 |
| 周三 | gRPC协议 | Protocol Buffers、RPC | 使用gRPC实现微服务通信 |
| 周四 | RESTful API | 设计原则、最佳实践 | 设计RESTful接口 |
| 周五 | 实践练习1 | WebSocket聊天室 | 实现实时消息推送 |
| 周六 | 实践练习2 | gRPC服务 | 实现gRPC服务端与客户端 |
| 周日 | 总结复习 | 整理笔记 | 总结各协议的应用场景 |
详细学习内容
周一:DNS协议
1. DNS查询过程
1. 客户端查询本地DNS缓存
2. 查询本地DNS服务器
3. 本地DNS查询根域名服务器(.)
4. 根服务器返回顶级域名服务器(.com)
5. 顶级域名服务器返回权威域名服务器(example.com)
6. 权威域名服务器返回最终IP地址
2. DNS记录类型
| 类型 | 说明 | 示例 |
|---|---|---|
| A | IPv4地址 | www.example.com → 93.184.216.34 |
| AAAA | IPv6地址 | www.example.com → 2606:2800:220:1:248:1893:25c8:1946 |
| CNAME | 别名 | www → example.com |
| MX | 邮件服务器 | @ → mail.example.com |
| TXT | 文本记录 | @ → "v=spf1 include:_spf.google.com ~all" |
周二:WebSocket协议
1. WebSocket握手
客户端请求:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
服务器响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
2. Spring WebSocket实现
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chatHandler(), "/chat")
.setAllowedOrigins("*");
}
@Bean
public ChatHandler chatHandler() {
return new ChatHandler();
}
}
周三:gRPC协议
1. Protocol Buffers定义
syntax = "proto3";
option java_package = "com.example.grpc";
option java_outer_classname = "UserProto";
service UserService {
rpc GetUser(GetUserRequest) returns (User);
rpc CreateUser(CreateUserRequest) returns (User);
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}
message User {
int64 id = 1;
string name = 2;
string email = 3;
}
周四:RESTful API设计
1. URL设计规范
# 良好的设计
GET /api/users # 获取用户列表
GET /api/users/{id} # 获取指定用户
POST /api/users # 创建用户
PUT /api/users/{id} # 更新用户
DELETE /api/users/{id} # 删除用户
GET /api/users/{id}/orders # 获取用户的订单
# 不好的设计
GET /api/getUsers
GET /api/createUser
POST /api/deleteUser?id=1
Java实践任务
- WebSocket实现
- gRPC服务实现
- 对比WebSocket与长轮询的性能
第11周:微服务与分布式网络
学习目标
- 理解微服务架构中的网络通信
- 掌握服务发现、负载均衡、API网关
- 学习分布式系统的网络模式
学习安排
| 日期 | 学习主题 | 重点内容 | Java结合实践 |
|---|---|---|---|
| 周一 | 服务发现 | 注册中心、健康检查 | 使用Nacos/Eureka |
| 周二 | 负载均衡 | 算法、客户端/服务端 | 使用Ribbon/LoadBalancer |
| 周三 | API网关 | 路由、限流、熔断 | 使用Spring Cloud Gateway |
| 周四 | RPC框架 | Dubbo、gRPC | Dubbo服务开发 |
| 周五 | 实践练习1 | 搭建微服务 | Spring Cloud实战 |
| 周六 | 实践练习2 | 链路追踪 | 使用SkyWalking/Zipkin |
| 周日 | 总结复习 | 整理笔记 | 总结微服务网络通信模式 |
详细学习内容
周一:服务发现
1. 注册中心对比
| 特性 | Eureka | Nacos | Consul | Zookeeper |
|---|---|---|---|---|
| CAP | AP | AP/CP | CP | CP |
| 健康检查 | 支持 | 支持 | 支持 | 支持 |
2. Nacos服务注册
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
group: DEFAULT_GROUP
周二:负载均衡
1. 负载均衡算法
随机算法:
随机选择一个服务器
轮询算法:
按顺序依次选择服务器
1 → 2 → 3 → 1 → 2 → 3 ...
加权轮询:
根据权重分配请求
服务器A(权重3) : 服务器B(权重1) = 3:1
最少连接:
选择当前连接数最少的服务器
一致性哈希:
相同请求路由到同一服务器
周三:API网关
1. API网关功能
- 路由转发:将请求路由到后端服务
- 负载均衡:分发请求到多个服务实例
- 限流熔断:保护后端服务
- 认证鉴权:统一的安全控制
2. Spring Cloud Gateway配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
周四:RPC框架
1. Dubbo架构
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Provider│ ────▶│ Registry│ ◀────│Consumer │
│ (服务端) │ │ (注册中心)│ │ (客户端) │
└─────────┘ └─────────┘ └─────────┘
▲ │
│ │
└──────────────────────────────────┘
Monitor
(监控中心)
Java实践任务
- Spring Cloud服务调用
- 配置负载均衡策略
- 实现熔断降级
第五阶段:综合实战与面试准备(第12周)
第12周:综合项目与面试准备
学习目标
- 综合运用所学知识完成实战项目
- 整理网络相关的面试题
- 制定持续学习计划
学习安排
| 日期 | 学习主题 | 内容 |
|---|---|---|
| 周一 | 实战项目1 | 实现一个简单的HTTP服务器 |
| 周二 | 实战项目2 | 实现一个RPC框架 |
| 周三 | 实战项目3 | 实现一个即时通讯系统 |
| 周四 | 面试题整理 | 整理计算机网络常见面试题 |
| 周五 | 面试题整理 | 整理Java网络编程面试题 |
| 周六 | 综合测试 | 完成综合测验 |
| 周日 | 总结反思 | 制定后续学习计划 |
常见面试题汇总
TCP/IP基础
- TCP三次握手和四次挥手的过程,为什么需要三次握手?
- TIME_WAIT状态的作用和危害
- TCP粘包拆包的原因和解决方案
- TCP和UDP的区别及应用场景
- HTTP和HTTPS的区别,HTTPS的建立过程
- 输入URL到页面显示的全过程
HTTP协议
- HTTP 1.0/1.1/2.0/3.0的主要区别
- HTTP状态码的含义
- HTTP缓存机制(强缓存和协商缓存)
- HTTP长连接和短连接
- HTTPS的加密过程
Java网络编程
- BIO、NIO、AIO的区别
- Netty的线程模型
- 如何实现心跳检测
- 如何处理TCP粘包拆包
- Socket的常用参数及调优
微服务网络
- 服务发现的原理
- 负载均衡算法
- 熔断降级机制
- API网关的作用
- 分布式事务解决方案
推荐书籍与资源
书籍
- 《计算机网络(第8版)》谢希仁 - 系统理论学习
- 《图解TCP/IP》- 入门理解
- 《TCP/IP详解 卷1:协议》- 深入理解
- 《Unix网络编程卷1:套接字联网API》- 编程实践
- 《Netty实战》- Java网络编程
在线资源
- Stanford CS144 - 计算机网络课程
- Wireshark官方文档
- Netty官方文档
- Spring Cloud官方文档
工具
- Wireshark - 网络抓包分析
- tcpdump - 命令行抓包
- Postman - HTTP测试
- JMeter - 性能测试
学习成果检验
每周检验
- 完成每周的实践练习
- 整理学习笔记
- 编写博客记录学习心得
阶段检验
- 第一阶段:能够使用Wireshark分析网络包
- 第二阶段:能够配置和诊断网络问题
- 第三阶段:能够进行Socket编程和TCP调优
- 第四阶段:能够开发基于HTTP/WebSocket的应用
- 第五阶段:能够完成综合实战项目
最终检验
- 独立实现一个HTTP服务器
- 独立实现一个RPC框架
- 能够解答常见的计算机网络面试题
- 能够排查和解决生产环境中的网络问题
持续学习计划
完成12周学习后,可以继续深入学习以下内容:
-
网络性能优化
- JVM网络参数调优
- 操作系统网络参数调优
- CDN原理与应用
-
网络安全
- SSL/TLS深入理解
- OAuth2.0与JWT
- API安全最佳实践
-
云原生网络
- Docker网络
- Kubernetes网络模型
- Service Mesh(Istio)
-
新型网络技术
- HTTP/3(QUIC协议)
- WebRTC
- gRPC-Web
附录:学习笔记模板
每周学习记录模板
## 第X周学习记录
### 本周学习目标
- [ ] 目标1
- [ ] 目标2
### 学习笔记
#### 周一:xxx
- 核心概念:
- 重点内容:
- 疑问点:
#### 周二:xxx
...
### Java实践
- 实践内容:
- 遇到问题:
- 解决方案:
- 代码要点:
### 本周总结
- 收获:
- 不足:
- 下周改进:
文档生成时间:2025年 计划执行周期:12周 祝学习顺利!
更多推荐




所有评论(0)