第 1 章 先认识网络通信
1.1 两个程序怎样找到对方
把服务器理解为“等待请求并处理请求的程序”,客户端是“主动发起请求的程序”。这两种身份取决于它们在一次通信中的角色,同一个程序也可以同时充当二者。
IP 地址帮助定位网络中的主机,端口帮助操作系统把数据交给某个监听程序。127.0.0.1:8080 的含义是:当前这台机器的 8080 端口。localhost 通常指向本机,但可能解析为 IPv4 或 IPv6;本书明确使用 IPv4 地址,减少初学时的变量。
一个 TCP 连接通常用源 IP、源端口、目标 IP、目标端口这四个量区分。客户端也有端口,只是通常由操作系统临时分配。服务器的监听端口不能无限重复占用;启动两份相同服务时常会看到地址已被使用的错误。
1.2 TCP 提供什么
TCP 提供可靠、有序的字节流。正常建立连接后,如果对端应用持续读取,你发送的字节会按顺序交给它;发生无法恢复的网络故障时,应用需要处理失败或超时。
这里最容易误解的是“字节流”。假设客户端连续发送:
hello\n
world\n
服务器可能一次读到 hello\nworld\n,也可能分三次读到 he、llo\nwo、rld\n。一次发送和一次接收没有一一对应关系。TCP 不知道哪个字节代表“一条业务消息”。
所以协议必须约定边界。本书前半部分规定:一条消息以换行符结束,内容采用 UTF-8,正文最长 1024 字节。换行符在 Java 字符串中写成 \n。在实际网络中发送的是换行字节,而不是反斜线与字母 n 两个字符。
1.3 UDP、HTTP 与 Netty 的位置
UDP 保留数据报边界,但不保证送达和有序,适合能自行容忍或补偿丢包的场景。HTTP 是应用层协议;常见的 HTTP/1.1 和 HTTP/2 通常运行在 TCP 之上,HTTP/3 则基于 QUIC。不能把“HTTP”和“TCP”当成同层替代品。
Netty 可以处理多种传输与协议。学 Netty 时先从 TCP 开始,是因为更容易直接看到连接、字节和消息边界之间的关系。
动手想一想: 客户端连续调用两次发送,为什么服务器不一定收到两条完整消息?