读写套接字
让我们看一个简单的示例,该示例说明程序如何使用Socket
类构建与服务器程序的连接,然后,Client 端如何通过套接字向服务器发送数据和从服务器接收数据。
该示例程序实现了一个 Client 端EchoClient,该 Client 端连接到回显服务器。回显服务器从其 Client 端接收数据并将其回显。示例EchoServer实现了回显服务器。 (或者,Client 端可以连接到支持Echo Protocol的任何主机。)
EchoClient
示例创建一个套接字,从而获得与回显服务器的连接。它从用户在标准 Importing 流上读取 Importing,然后通过将文本写入套接字将文本转发到回显服务器。服务器通过套接字将 Importing 回显到 Client 端。Client 端程序读取并显示从服务器传递回去的数据。
请注意,EchoClient
示例向其套接字写入和从套接字读取数据,从而向回显服务器发送数据并从其接收数据。
让我们遍历该程序并研究有趣的部分。 EchoClient
示例中的try-with-resources语句中的以下语句很关键。这些行在 Client 端和服务器之间构建套接字连接,并在套接字上打开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 resources 语句中的第一条语句创建一个新的Socket对象,并将其命名为echoSocket
。此处使用的Socket
构造函数需要计算机的名称和您要连接的端口号。该示例程序使用第一个command-line argument作为计算机名(主机名),第二个命令行参数作为端口号。在计算机上运行该程序时,请确保所使用的主机名是要连接的计算机的标准 IP 名称。例如,如果您的回显服务器正在计算机echoserver.example.com
上运行并且正在侦听端口号 7,如果您想将EchoServer
示例用作回显服务器,请首先从计算机echoserver.example.com
运行以下命令:
java EchoServer 7
然后,使用以下命令运行EchoClient
示例:
java EchoClient echoserver.example.com 7
try
-with resources 语句中的第二条语句获取套接字的输出流,并在其上打开PrintWriter
。同样,第三条语句获取套接字的 Importing 流,并在其上打开一个BufferedReader
。该示例使用读取器和写入器,以便可以在套接字上写入 Unicode 字符。
要将数据通过套接字发送到服务器,EchoClient
示例需要写入PrintWriter
。为了获得服务器的响应,EchoClient
从BufferedReader
对象stdIn
读取,该对象是在try
-with resources 语句的第四条语句中创建的。如果您还不熟悉 Java 平台的 I/O 类,则不妨阅读Basic I/O。
该程序的下一个有趣部分是while
循环。循环一次从标准 Importing 流中读取一行,并通过将其写入连接到套接字的PrintWriter
立即将其发送到服务器:
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
while
循环中的最后一条语句从连接到套接字的BufferedReader
读取一行信息。 readLine
方法 await,直到服务器将信息回显到EchoClient
为止。 readline
返回时,EchoClient
将信息打印到标准输出。
while
循环 continue 进行,直到用户键入 Importing 结束字符为止。也就是说,EchoClient
示例从用户读取 Importing,将其发送到 Echo 服务器,从服务器获取响应,然后显示它,直到到达 Importing 结束为止。 (您可以通过按 Ctrl-C 来键入 Importing 结束字符.)然后while
循环终止,并且 Java 运行时会自动关闭连接到套接字和标准 Importing 流的读取器和写入器,并且它关闭与服务器的套接字连接。 Java 运行时会自动关闭这些资源,因为它们是在try
-with-resources 语句中创建的。 Java 运行时以与创建资源相反的 Sequences 关闭这些资源。 (这很好,因为在关闭套接字本身之前,应先关闭连接到套接字的流.)
该 Client 端程序简单明了,因为回显服务器实现了简单的协议。Client 端将文本发送到服务器,然后服务器将其回显。当您的 Client 端程序与更复杂的服务器(例如 HTTP 服务器)进行通信时,您的 Client 端程序也将更加复杂。但是,基本知识与该程序基本相同:
-
打开 socket。
-
打开 Importing 流并将输出流输出到套接字。
-
根据服务器协议从流中读取和写入流。
-
关闭流。
-
关闭 socket。
Client 端与 Client 端之间仅第 3 步有所不同,具体取决于服务器。其他步骤大致相同。