读取和写入套接字
原文: 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 因客户端而异,具体取决于服务器。其他步骤基本保持不变。
