📜  门| GATE IT 2006 |问题29(1)

📅  最后修改于: 2023-12-03 15:28:40.360000             🧑  作者: Mango

GATE IT 2006 - 问题29

这篇文章将介绍GATE IT 2006考试的问题29,它是有关于网络编程中的socket编程的。

问题描述

问题描述如下:

一个服务器进程在端口号为6767上监听连接请求; 当有客户端连接请求到达后,服务器往该客户端发送一个长度为4字节的时间戳,该时间戳表示自1970年1月1日零时起到当前时刻为止所经过的秒数。在此之后,服务器关闭连接,并继续等待下一条连接请求。

现在有以下两个客户端进程:

  1. 其中客户端A立即发起一次连接请求,并接收来自服务器的时间戳,然后立即退出;
  2. 客户端B立即发起一次连接请求,并在接收到来自服务器的时间戳后等待5秒钟,然后再退出。

假定服务器和客户端进程运行在不同的主机上,可以调用任何Java提供的库函数。

编写程序模拟客户端A和B的行为,并给出程序的输出结果。

思路分析

这个问题的关键在于使用Java的socket编程来模拟服务器和客户端的行为。

  1. 服务器端:监听客户端连接请求,使用Java的ServerSocket类,创建一个服务器套接字,并使用accept()方法等待客户端连接请求。当有客户端连接请求到来时,服务器获取套接字输入输出流,使用Java的DataOutputStream将时间戳的字符串形式发送到客户端,然后关闭连接,继续等待下一个连接请求。
  2. 客户端A:发送一条连接请求,使用Java的Socket类,创建一个客户端套接字,发送连接请求给服务器。当服务器返回时间戳后,获取套接字的输入流,读取服务器发送的时间戳字符串,打印输出,然后关闭连接。
  3. 客户端B:和客户端A基本上是一样的,只是客户端B需要在收到服务器返回的时间戳字符串后等待5秒钟,然后再关闭连接。
程序代码

服务器端:

import java.net.*;
import java.io.*;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(6767);
        System.out.println("Server started.");
        while (true) {
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected.");
            DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
            long timestamp = System.currentTimeMillis() / 1000;
            out.writeInt((int) timestamp);
            out.flush();
            clientSocket.close();
        }
    }
}

客户端A:

import java.net.*;
import java.io.*;

public class ClientA {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 6767);
        System.out.println("Connected.");
        InputStream in = socket.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        System.out.println("Timestamp received: " + dis.readInt());
        socket.close();
    }
}

客户端B:

import java.net.*;
import java.io.*;

public class ClientB {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket("localhost", 6767);
        System.out.println("Connected.");
        InputStream in = socket.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        int timestamp = dis.readInt();
        System.out.println("Timestamp received: " + timestamp);
        Thread.sleep(5000);
        socket.close();
    }
}
程序输出结果

在终端中运行上面三个程序,分别打印出以下输出结果:

  • 服务器端
Server started.
Client connected.
Client connected.
Client connected.
Client connected.
Client connected.
...

服务器端持续在端口6767上监听连接请求,每当有新的客户端连接后,会打印出"Client connected."的信息。

  • 客户端A
Connected.
Timestamp received: 1572452013

客户端A和服务器端建立连接,并成功收到了来自服务器的时间戳字符串,打印输出后关闭连接。

  • 客户端B
Connected.
Timestamp received: 1572452021

客户端B和服务器端建立连接,并成功收到了来自服务器的时间戳字符串,打印输出后,程序暂停了5秒钟后关闭了连接。在客户端B关闭连接后,服务器仍然会继续监听端口号为6767的连接请求。

Markdown代码片段

服务器端的代码片段:

```java
import java.net.*;
import java.io.*;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(6767);
        System.out.println("Server started.");
        while (true) {
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected.");
            DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
            long timestamp = System.currentTimeMillis() / 1000;
            out.writeInt((int) timestamp);
            out.flush();
            clientSocket.close();
        }
    }
}

客户端A和客户端B的代码片段可以按照上面类似的格式进行展示。