Jakob Jenkov 2024-05-30
Java 内置了一套相当易用的网络编程 API,使得通过 TCP/IP 套接字或 UDP 套接字在互联网上进行通信变得非常简单。通常 TCP 的使用频率高于 UDP,但本教程将对两者都进行说明。
尽管 Java 网络 API 允许你通过套接字打开和关闭网络连接,但所有通信实际上都是通过 Java IO 类 InputStream 和 OutputStream 完成的。
此外,你也可以使用 Java NIO API 中的网络类。这些类与 Java 网络 API 中的类类似,不同之处在于 Java NIO API 可以工作在非阻塞模式下。在某些场景中,非阻塞模式可能会带来性能提升。
Java TCP 网络编程基础
通常,客户端会向服务器发起一个 TCP/IP 连接。建立连接后,客户端开始与服务器通信。当客户端完成通信后,它会关闭该连接。下图展示了这一过程:
一个客户端可以通过一个已打开的连接发送多个请求。事实上,只要服务器愿意接收,客户端就可以持续发送任意多的数据。同样,如果服务器希望,它也可以主动关闭连接。
Java 的 Socket 与 ServerSocket
当客户端想要向服务器发起一个 TCP/IP 连接时,它会使用 Java Socket。你只需告诉 Socket 要连接的目标 IP 地址和 TCP 端口号,其余工作由 Java 自动处理。
如果你想启动一个监听某个 TCP 端口上客户端连接请求的服务器,则需要使用 Java ServerSocket。当客户端通过其 Socket 连接到服务器的 ServerSocket 时,服务器会为该连接分配一个新的 Socket 实例。此后,客户端和服务器就通过各自的 Socket 实例进行通信。
关于 Socket 和 ServerSocket 的更多细节将在后续章节中详细讲解。
Java UDP 网络编程基础
UDP 的工作方式与 TCP 有所不同。使用 UDP 时,客户端与服务器之间没有连接。客户端可以向服务器发送数据,而服务器可能(也可能不)接收到这些数据。客户端永远不会知道数据是否被对方成功接收。反方向(服务器到客户端)也是如此。
由于没有数据送达保证,UDP 协议的协议开销更小。
在某些特定场景下,无连接的 UDP 模型比 TCP 更合适。这些场景将在关于 Java UDP DatagramSocket 的专门章节中详细讨论。