Java Socket官方文档学习(二)

本文介绍了如何使用JavaSocket创建一个客户端和服务器端应用程序。客户端通过Socket连接到服务器,而服务器使用ServerSocket监听并接受连接。KnockKnock协议用于处理交互,包括初始化对话和响应客户端输入。文章提供了具体的代码示例,展示了如何读写数据并管理通讯状态。
摘要由CSDN通过智能技术生成

Java Socket官方文档学习(二)

如何写一个客户端和服务器对

这片文章的内容基本来自Java Socket官方文档的最后一个部分,如何写一个客户端和服务器对:https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html

The example consists of two independently running Java programs: the client program and the server program. The client program is implemented by a single class, KnockKnockClient, and is very similar to the EchoClient example from the previous section. The server program is implemented by two classes: KnockKnockServer and KnockKnockProtocol. KnockKnockServer, which is similar to EchoServer, contains the main method for the server program and performs the work of listening to the port, establishing connections, and reading from and writing to the socket. The class KnockKnockProtocol serves up the jokes. It keeps track of the current joke, the current state (sent knock knock, sent clue, and so on), and returns the various text pieces of the joke depending on the current state. This object implements the protocol—the language that the client and server have agreed to use to communicate.

文档中说这个例子中包含两个独立运行的Java程序,其中一个是服务端另一个是客户端程序。客户端程序实现了KnockKnockClient类,文档说它和先前的Echo Client比较像,可以看《Java Socket官方文档学习(一)》。服务端继承了两个类 KnockKnockServer and KnockKnockProtocol。这个东西和先前的Echo Server比较相似。文档说服务端程序包含程序入口,建立链接,向Socket读写和监听的功能。 KnockKnockProtocol这个类提供笑话,它追踪当前的笑话和当前的状态,根据笑话的当前笑话返回笑话的文档。

服务端部分

KnockKnockServer的源码:https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KnockKnockServer.java

这个Server开始创建了一个SocketServer实例来监听某一个特定的端口,在这个案例中,Socket Server的端口是4444

int portNumber = Integer.parseInt(args[0]);

try ( 
    ServerSocket serverSocket = new ServerSocket(portNumber);
    Socket clientSocket = serverSocket.accept();
    PrintWriter out =
        new PrintWriter(clientSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(clientSocket.getInputStream()));
) {

ServerSocket is a java.net class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket throws an exception if it can’t listen on the specified port (for example, the port is already being used). In this case, the KnockKnockServer has no choice but to exit.

文档说ServerSocket是Java.net包中的一个类,它提供了一个独立于系统的服务端Socket链接的实现。当这个实例不能监听某一特定端口时(比如端口被占用了),它的构造方法会抛出一个异常。在这种情况下,服务器别无选择只能终止运行。

如果服务器成功绑定到了它的目标端口,ServerSocket对象就会被创建,随后服务会执行下一步————接收客户端的链接。

具体实现是这个代码:clientSocket = serverSocket.accept();

ServerSocket类中的accept()方法会等待直到客户端发起在特定端口链接主机的请求。当建立链接的请求被成功接收时,accpet()方法会返回一个已经绑定到该端口的Socket对象。通过这个Socket对象,服务端和客户端可以进行通讯,原ServerSocket用于监听客户端的链接请求。但是在该案例中,并不实现这个功能。引文:https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later

中介绍了这个功能如何实现。

当客户端和服务器成功建立起链接之后,通讯部分代码块如下:

try (
    // ...
    PrintWriter out =
        new PrintWriter(clientSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(clientSocket.getInputStream()));
) {
    String inputLine, outputLine;
            
    // Initiate conversation with client
    KnockKnockProtocol kkp = new KnockKnockProtocol();
    outputLine = kkp.processInput(null);
    out.println(outputLine);

    while ((inputLine = in.readLine()) != null) {
        outputLine = kkp.processInput(inputLine);
        out.println(outputLine);
        if (outputLine.equals("Bye."))
            break;
    }

以上代码块实现了如下三个功能:
1.获得Socket的输入和输出流,并且在这些流上建立reader和writer。
2.通过客户端向Socket写入初始化通讯。
3.通过向Socket读写和客户端进行通讯。(注意这个While循环)

客户端部分

当启动客户端时,服务端的程序应该已经开始运行并监听指定端口,等待一个客户端发起链接。所以客户端程序要做的第一件事就是创建一个用于链接到特定host、特定
端口的Socket。

String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);

try (
    Socket kkSocket = new Socket(hostName, portNumber);
    PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(kkSocket.getInputStream()));
)

《Java Socket官方文档学习(一)》有解读过类似的代码块。

接下来程序通过While循环体来实现和服务端的通信,客户端通过监听Socket的输入流来监听服务端发回的数据。如果服务端发送Bye,则终端链接。

while ((fromServer = in.readLine()) != null) {
    System.out.println("Server: " + fromServer);
    if (fromServer.equals("Bye."))
        break;

    fromUser = stdIn.readLine();
    if (fromUser != null) {
        System.out.println("Client: " + fromUser);
        out.println(fromUser);
    }
}

这两个案例程序都是可以在本地跑的,Java Socket官方文档这个做的比较有意思,文章结尾最后附上客户端和服务端源码的链接。

客户端:https://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoClient.java
服务端:https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KnockKnockServer.java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值