读取和写入套接字
原文: https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
让我们看一个简单的例子,说明程序如何使用Socket
类建立与服务器程序的连接,然后,客户端如何通过套接字向服务器发送数据和从服务器接收数据。
示例程序实现了一个连接到 echo 服务器的客户端 EchoClient
。 echo 服务器从其客户端接收数据并将其回送。示例 EchoServer
实现了一个 echo 服务器。 (或者,客户端可以连接到支持回声协议的任何主机。)
EchoClient
示例创建一个套接字,从而获得与 echo 服务器的连接。它在标准输入流上读取用户的输入,然后通过将文本写入套接字将该文本转发到 echo 服务器。服务器通过套接字将输入回送给客户端。客户端程序读取并显示从服务器传回给它的数据。
请注意,EchoClient
示例写入和读取其套接字,从而向 echo 服务器发送数据和从 echo 服务器接收数据。
让我们来看看程序并研究有趣的部分。 EchoClient
示例中 try
-with-resources 语句中的以下语句至关重要。这些行在客户端和服务器之间建立套接字连接,并在套接字上打开 PrintWriter
和 BufferedReader
:
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
)
try
-with 资源语句中的第一个语句创建一个新的 Socket
对象并将其命名为echoSocket
。此处使用的Socket
构造器需要计算机的名称和要连接的端口号。示例程序使用第一个命令行参数作为计算机名称(主机名),使用第二个命令行参数作为端口号。在计算机上运行此程序时,请确保您使用的主机名是要连接的计算机的完全限定 IP 名称。例如,如果您的 echo 服务器正在计算机echoserver.example.com
上运行并且正在侦听端口号 7,那么如果要将EchoServer
示例用作 echo 服务器,请首先从计算机echoserver.example.com
运行以下命令:
java EchoServer 7
然后,使用以下命令运行EchoClient
示例:
java EchoClient echoserver.example.com 7
try
-with resources 语句中的第二个语句获取套接字的输出流并在其上打开PrintWriter
。类似地,第三个语句获取套接字的输入流并在其上打开BufferedReader
。该示例使用读取器和写入器,以便它可以在套接字上写入 Unicode 字符。
要通过套接字将数据发送到服务器,EchoClient
示例需要写入PrintWriter
。要获取服务器的响应,EchoClient
从BufferedReader
对象stdIn
读取,该对象在try
-with 资源语句的第四个语句中创建。如果您还不熟悉 Java 平台的 I / O 类,您可能希望阅读 Basic I / O 。
该程序的下一个有趣部分是while
循环。循环从标准输入流一次读取一行,并通过将其写入连接到套接字的PrintWriter
立即将其发送到服务器:
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
while
循环中的最后一个语句从连接到套接字的BufferedReader
读取一行信息。 readLine
方法等待,直到服务器将信息回送回EchoClient
。当readline
返回时,EchoClient
将信息打印到标准输出。
while
循环继续,直到用户键入输入结束字符。也就是说,EchoClient
示例从用户读取输入,将其发送到 Echo 服务器,从服务器获取响应并显示它,直到它到达输入结束。 (您可以通过按 Ctrl-C 键入输入结束字符。)然后while
循环终止,Java 运行时自动关闭连接到套接字和标准的读取器和写入器输入流,它关闭到服务器的套接字连接。 Java 运行时会自动关闭这些资源,因为它们是在try
-with-resources 语句中创建的。 Java 运行时以与创建它们相反的顺序关闭这些资源。 (这很好,因为连接到套接字的流应该在套接字本身关闭之前关闭。)
此客户端程序简单明了,因为 echo 服务器实现了一个简单的协议。客户端将文本发送到服务器,服务器回送它。当您的客户端程序与更复杂的服务器(如 HTTP 服务器)通信时,您的客户端程序也会更复杂。但是,基础知识与此计划中的基本内容大致相同:
- 打开一个插座。
- 打开输入流并将输出流输出到套接字。
- 根据服务器协议读取和写入流。
- 关闭溪流。
- 关闭插座。
只有步骤 3 因客户端而异,具体取决于服务器。其他步骤基本保持不变。