🌐 漫画计算机网络基础
🎯 学习目标:掌握计算机网络核心原理,为分布式系统和网络编程打下坚实基础
📋 目录
🎭 漫画引言
小明: “为什么我的API调用有时候快有时候慢?”
架构师老王: “这就要从网络通信说起了!网络就像邮政系统,数据包就是信件…”
🏗️ OSI七层模型与TCP/IP
🎨 漫画场景:网络邮政系统
发送方 接收方
┌──────────┐ ┌──────────┐
│应用层 📱 │ ←→ HTTP请求/响应 ←→ │应用层 🖥️ │
├──────────┤ ├──────────┤
│传输层 📦 │ ←→ TCP/UDP分段 ←→ │传输层 📦 │
├──────────┤ ├──────────┤
│网络层 🗺️ │ ←→ IP路由选择 ←→ │网络层 🗺️ │
├──────────┤ ├──────────┤
│数据链路层│ ←→ 以太网帧 ←→ │数据链路层│
├──────────┤ ├──────────┤
│物理层 ⚡ │ ←→ 电信号传输 ←→ │物理层 ⚡ │
└──────────┘ └──────────┘
📚 网络协议栈实现
/**
* 网络协议栈模拟器
*/
public class NetworkProtocolStack {
// 应用层 - HTTP协议
static class ApplicationLayer {
public HttpRequest createHttpRequest(String method, String url, String body) {
HttpRequest request = new HttpRequest();
request.method = method;
request.url = url;
request.body = body;
request.headers.put("Content-Type", "application/json");
request.headers.put("User-Agent", "Java-Client/1.0");
System.out.println("应用层:创建HTTP请求 " + method + " " + url);
return request;
}
public HttpResponse parseHttpResponse(String responseData) {
HttpResponse response = new HttpResponse();
String[] lines = responseData.split("\n");
// 解析状态行
String statusLine = lines[0];
response.statusCode = Integer.parseInt(statusLine.split(" ")[1]);
System.out.println("应用层:解析HTTP响应,状态码:" + response.statusCode);
return response;
}
}
// 传输层 - TCP协议
static class TransportLayer {
public List<TcpSegment> segmentData(byte[] data, int sourcePort, int destPort) {
List<TcpSegment> segments = new ArrayList<>();
int mss = 1460; // 最大分段大小
for (int i = 0; i < data.length; i += mss) {
int segmentSize = Math.min(mss, data.length - i);
byte[] segmentData = Arrays.copyOfRange(data, i, i + segmentSize);
TcpSegment segment = new TcpSegment();
segment.sourcePort = sourcePort;
segment.destPort = destPort;
segment.sequenceNumber = i;
segment.data = segmentData;
segment.checksum = calculateChecksum(segmentData);
segments.add(segment);
}
System.out.println("传输层:数据分段,共" + segments.size() + "个TCP段");
return segments;
}
private int calculateChecksum(byte[] data) {
int checksum = 0;
for (byte b : data) {
checksum += b & 0xFF;
}
return checksum & 0xFFFF;
}
}
// 网络层 - IP协议
static class NetworkLayer {
public IpPacket createIpPacket(TcpSegment segment, String sourceIp, String destIp) {
IpPacket packet = new IpPacket();
packet.version = 4; // IPv4
packet.headerLength = 20;
packet.totalLength = 20 + segment.data.length;
packet.sourceIp = sourceIp;
packet.destIp = destIp;
packet.protocol = 6; // TCP协议号
packet.payload = segment;
System.out.println("网络层:创建IP数据包 " + sourceIp + " -> " + destIp);
return packet;
}
public String routePacket(IpPacket packet) {
// 简化的路由选择
String[] destParts = packet.destIp.split("\\.");
int network = Integer.parseInt(destParts[0]);
if (network == 192) {
System.out.println("网络层:本地网络,直接投递");
return "local";
} else {
System.out.println("网络层:远程网络,通过路由器转发");
return "router";
}
}
}
// 数据结构定义
static class HttpRequest {
String method;
String url;
String body;
Map<String, String> headers = new HashMap<>();
}
static class HttpResponse {
int statusCode;
String body;
Map<String, String> headers = new HashMap<>();
}
static class TcpSegment {
int sourcePort;
int destPort;
long sequenceNumber;
long acknowledgmentNumber;
byte[] data;
int checksum;
}
static class IpPacket {
int version;
int headerLength;
int totalLength;
String sourceIp;
String destIp;
int protocol;
Object payload;
}
}
🌐 HTTP/HTTPS协议详解
📡 HTTP协议工作流程
/**
* HTTP协议模拟器
*/
public class HttpProtocolSimulator {
// HTTP客户端
static class HttpClient {
private Socket socket;
public HttpResponse sendRequest(String host, int port, HttpRequest request) {
try {
// 建立TCP连接
socket = new Socket(host, port);
System.out.println("建立TCP连接:" + host + ":" + port);
// 发送HTTP请求
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 构造HTTP请求报文
StringBuilder requestBuilder = new StringBuilder();
requestBuilder.append(request.method).append(" ").append(request.path).append(" HTTP/1.1\r\n");
requestBuilder.append("Host: ").append(host).append("\r\n");
requestBuilder.append("Connection: keep-alive\r\n");
for (Map.Entry<String, String> header : request.headers.entrySet()) {
requestBuilder.append(header.getKey()).append(": ").append(header.getValue()).append("\r\n");
}
requestBuilder.append("\r\n");
if (request.body != null) {
requestBuilder.append(request.body);
}
System.out.println("发送HTTP请求:\n" + requestBuilder.toString());
out.print(requestBuilder.toString());
out.flush();
// 接收HTTP响应
HttpResponse response = parseResponse(in);
return response;
} catch (IOException e) {
System.err.println("HTTP请求失败:" + e.getMessage());
return null;
}
}
private HttpResponse parseResponse(Buffer