Java 中的旧版套接字 API
Unix 操作系统的旧版套接字 API 提供了一组用于网络通信的编程接口。尽管创建了更现代的网络 API,但它已被广泛使用了 30 多年,至今仍在使用。
借助由一组函数组成的 API,应用程序可以构建套接字并通过网络进行通信。套接字是一种软件端点,可促进程序之间的网络通信。面向连接的套接字和无连接套接字是 API 提供的两种套接字类型。
实现
根据此 JEP,新的 NioSocketImpl 实现将取代 SocketImpl 实现。这种方法通过使用与 NIO(新 I/O)实现相同的架构并与当前的缓冲区缓存技术集成,消除了对线程堆栈的必要性。这些调整中还包括许多其他有用的调整,包括 java.lang.ref。如果在未关闭的套接字上对 SocketImpl 实现进行垃圾收集,并且在轮询时 Socket 处于非阻塞模式时发生超时操作,则将使用更干净的方法来关闭套接字。
为了减少在重新实现已使用 20 多年的方法时出现问题的可能性,已经开发了一个系统属性来利用原始实现。
当指定 usePlainSocketImpl=true 时,将应用前面的实现。
应该强调的是,SocketImpl 是一种历史性的 SPI 方法,过去没有完全说明;当前版本尝试(如果可能)模仿未定义的行为。但是,有一些边缘情况会导致新方法失败,如这里所示。上述系统特性可用于解决除两个之外的所有问题。 FileInputStream 和 FileOutputStream 的早期实现返回输入和输出流,然后对其进行扩展。
对于当前实现,情况并非如此。使用自定义或平台 SocketImpl 的 ServerSockets 无法接受使用其他类型的 SocketImpl 返回 Sockets 的连接。
算法
最重要的步骤是实例化 Socket 对象,其中包括提供有关主机名以及您打算连接的端口号的详细信息。
与服务器进行对话需要从上述已建立的套接字对象创建输入和输出流,该套接字对象封装了传输过程中所需的所有必要数据。
完成后关闭套接字和流。
带有响应生成的 API 实现
示例
import java.net.*;
import java.io.*;
public class SocketExample {
public static void main(String[] args) {
try {
// 创建套接字
Socket socket = new Socket("localhost", 8080);
// 向服务器发送消息
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
writer.println("Hello, server!");
// 从服务器接收消息
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String response = reader.readLine();
System.out.println("Server response: " + response);
// 关闭套接字
socket.close();
} catch (UnknownHostException ex) {
System.out.println("Server not found: " + ex.getMessage());
} catch (IOException ex) {
System.out.println("I/O error: " + ex.getMessage());
}
}
}
输出

生成的结果可能因服务器无响应或通信故障导致的异常类型而异。例如,如果定位服务器失败,则生成的输出将显示为 -

此处的相关示例要求我们首先作为客户端远程连接到在端口号"8080"上启用的本地运行 TCP/IP(传输控制协议/Internet 协议)身份验证网络服务。接下来,只有在确保最佳连接性之后,我们才能继续托管最佳的基于"请求"的服务,同样,在需要时对协议/程序特定的错误进行适当的管理,同时还要优先考虑在成功交换后两个对等体之间先前进行的倾向/操作,这些对等体分别通过各自的 TCP/IP 集成主机/客户端系统接口连接安排 - 一旦完成;应通过静音所有合法通信通道来终止与其他网络节点的先前关联的取消源,而不会疏忽将系统资源恢复到其预先存在的默认值。
优点和缺点
由于几项关键的增强功能,与带来许多挑战的以前版本相比,维护 Java Socket API 变得简单得多。这应该会提高套接字代码的可靠性。
由于 NIO 在更低级别上工作,我们不需要对当前的 Socket 和 ServerSocket 类进行任何更改 - 好处显而易见!这些改进旨在简化维护流程并确保未来的可行性,Java 套接字编程的未来前景非常乐观,正如 JDK 中正在开发的 Project Loom 所见。
该项目探索了光纤的概念,这是对线程的全新视角(在我们之前的帖子中了解有关 Project Loom 的更多信息)。一旦 Project Loom 发布,NIO 实现将能够从中受益,而早期的实现将无效。这是可能的,因为 NIO 实现使用 java.util.concurrent 锁而不是同步方法。
无连接套接字用于不可靠的面向数据报的通信,而面向连接的套接字用于可靠的面向流的通信。
由于 API 级别较低,开发人员必须手动处理许多细节,包括数据包碎片和重组。虽然这可能很困难,但它也为开发人员提供了更多的自由和控制权。
值得注意的是,有多少公认的编程语言(包括但不限于 - C、C++ 和 Python)已经非常重视在其环境中实现非常有用的 Legacy Socket API。虽然最近的网络技术(例如 gRPC 或 WebSocket)可能会因效率/抽象级别的提高而黯然失色,但传统套接字 API 仍然很有价值,因为它具有灵活性、自然的学习曲线,并且可以通过已在线部署和广泛部署在各个行业的广泛使用的应用程序集成到当今市场中。'
结论
对于基于 Unix 的系统中的网络连接,传统套接字 API 是一个广受欢迎的编程接口集合,已经存在了三十多年。开发人员可以借助由一组函数组成的 API 构建套接字并通过网络进行通信。面向连接的套接字和无连接套接字分别提供可靠和不稳定的通信,这是 API 提供的两种套接字类型。
传统套接字 API 为开发人员提供了更多的自由和控制,但它也相当低级,需要手动处理许多细节。尽管创建了更现代的网络 API,但旧式套接字 API 仍然很有用,因为它易于使用、适应性强,并广泛应用于 C、C++ 和 Python 等众多编程语言。
在我们的示例中,我们展示了如何使用 Java 旧式套接字 API 构建套接字、发送和接收数据以及处理异常。这些程序的输出将由服务器的响应或引发的异常决定,如前面的响应中所述。
相关文章
有用资源
java 参考教程 - 该教程包含有关 java 的更多信息:https://www.cainiaomax.com/java/

