Socket多客户端通信

    服务端首先构造的是ServerSocket 对象,传入构造方法中的参数是端口号,同需连接客户端的端口号一致。接下来通过ServerSocket 对象的accept()方法来获取Socket对象,此方法被称为阻塞方法,该一直在运行,等待客户端发送的Socket连接请求,若未收到请求,accept()方法就一直在循环执行,始终不返回结果,直到收到请求后,accept()方法会返回发送请求的Socket 对象。

/**
 * Socket多客户端通信---服务端
 */
public class MultiTalkServer {
    static int clientNum = 0;
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;
        try {
            serverSocket = new ServerSocket(1234);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (listening){
            Socket socket = serverSocket.accept();
            new ServerThread(socket,clientNum).start();
            clientNum++;
        }
        serverSocket.close();
    }

    public static class ServerThread extends Thread{
        Socket socket = null;
        int clientNum;
        private ServerThread(Socket socket,int num){
            this.socket = socket;
            this.clientNum = num+1;
        }

        @Override
        public void run() {
            try {
                BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
                PrintWriter sendStream = new PrintWriter(socket.getOutputStream());
                BufferedReader recvStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println("Client:" + clientNum +" " + recvStream.readLine());

                String str = input.readLine();
                while (!str.equals("886")){
                    sendStream.println(str);
                    sendStream.flush();
                    System.out.println("Server:" + str);
                    System.out.println("Client:" + clientNum+" " + recvStream.readLine());
                    str = input.readLine();
                }
                sendStream.close();
                recvStream.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

   服务端 类中有个静态成员变量clientNum用来记录发起请求的客户端数量,构造ServerSocket对象,在while循环方法体创建ServerThread线程。相当于main 方法一直在循环等待客户端socket请求,一旦接收到socket请求,就实例化一个线程与之交互聊天,线程记录数量加一。

ServerThread的实现,内部维护了socket对象和客户端数量,run 方法中首先创建了三个流:

  • 一个输入流获取键盘输入,
  • 再用输出流将信息发送给对方网络,
  • 最后构造一个输入流获取响应的信息。

接下来判断键盘输入文本为“886”则停止发送,聊天结束;否则继续读取键盘输入流发送信息,最后关闭流和socket的连接。

一个客户端代码如下:多个可相同

public class TalkClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",1234);
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter sendStream = new PrintWriter(socket.getOutputStream());
            BufferedReader recvStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String str = input.readLine();
            while (!str.equals("886")){
                sendStream.println(str);
                sendStream.flush();
                System.out.println("Client: " + str);
                System.out.println("Server:" + recvStream.readLine());
                str = input.readLine();
            }
            sendStream.close();
            recvStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端与客户端的例子很大部分内容相同,只是服务端需要构造一个ServerSocket,通过ServerSocket得到和客户端连接的Socket对象,得到对象后可以构造输入、出流进行IO流的读写,最后关闭流、Socket即可。

猜你喜欢

转载自blog.csdn.net/weixin_38327420/article/details/83150735