读取和写入套接字

原文: 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 语句中的以下语句至关重要。这些行在客户端和服务器之间建立套接字连接,并在套接字上打开 PrintWriterBufferedReader

  1. String hostName = args[0];
  2. int portNumber = Integer.parseInt(args[1]);
  3. try (
  4. Socket echoSocket = new Socket(hostName, portNumber);
  5. PrintWriter out =
  6. new PrintWriter(echoSocket.getOutputStream(), true);
  7. BufferedReader in =
  8. new BufferedReader(
  9. new InputStreamReader(echoSocket.getInputStream()));
  10. BufferedReader stdIn =
  11. new BufferedReader(
  12. new InputStreamReader(System.in))
  13. )

try -with 资源语句中的第一个语句创建一个新的 Socket 对象并将其命名为echoSocket。此处使用的Socket构造器需要计算机的名称和要连接的端口号。示例程序使用第一个命令行参数作为计算机名称(主机名),使用第二个命令行参数作为端口号。在计算机上运行此程序时,请确保您使用的主机名是要连接的计算机的完全限定 IP 名称。例如,如果您的 echo 服务器正在计算机echoserver.example.com上运行并且正在侦听端口号 7,那么如果要将EchoServer示例用作 echo 服务器,请首先从计算机echoserver.example.com运行以下命令:

  1. java EchoServer 7

然后,使用以下命令运行EchoClient示例:

  1. java EchoClient echoserver.example.com 7

try -with resources 语句中的第二个语句获取套接字的输出流并在其上打开PrintWriter。类似地,第三个语句获取套接字的输入流并在其上打开BufferedReader。该示例使用读取器和写入器,以便它可以在套接字上写入 Unicode 字符。

要通过套接字将数据发送到服务器,EchoClient示例需要写入PrintWriter。要获取服务器的响应,EchoClientBufferedReader对象stdIn读取,该对象在try -with 资源语句的第四个语句中创建。如果您还不熟悉 Java 平台的 I / O 类,您可能希望阅读 Basic I / O

该程序的下一个有趣部分是while循环。循环从标准输入流一次读取一行,并通过将其写入连接到套接字的PrintWriter立即将其发送到服务器:

  1. String userInput;
  2. while ((userInput = stdIn.readLine()) != null) {
  3. out.println(userInput);
  4. System.out.println("echo: " + in.readLine());
  5. }

while循环中的最后一个语句从连接到套接字的BufferedReader读取一行信息。 readLine方法等待,直到服务器将信息回送回EchoClient。当readline返回时,EchoClient将信息打印到标准输出。

while循环继续,直到用户键入输入结束字符。也就是说,EchoClient示例从用户读取输入,将其发送到 Echo 服务器,从服务器获取响应并显示它,直到它到达输入结束。 (您可以通过按 Ctrl-C 键入输入结束字符。)然后while循环终止,Java 运行时自动关闭连接到套接字和标准的读取器和写入器输入流,它关闭到服务器的套接字连接。 Java 运行时会自动关闭这些资源,因为它们是在try -with-resources 语句中创建的。 Java 运行时以与创建它们相反的顺序关闭这些资源。 (这很好,因为连接到套接字的流应该在套接字本身关闭之前关闭。)

此客户端程序简单明了,因为 echo 服务器实现了一个简单的协议。客户端将文本发送到服务器,服务器回送它。当您的客户端程序与更复杂的服务器(如 HTTP 服务器)通信时,您的客户端程序也会更复杂。但是,基础知识与此计划中的基本内容大致相同:

  1. 打开一个插座。
  2. 打开输入流并将输出流输出到套接字。
  3. 根据服务器协议读取和写入流。
  4. 关闭溪流。
  5. 关闭插座。

只有步骤 3 因客户端而异,具体取决于服务器。其他步骤基本保持不变。