欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Socket多客户端通信

程序员文章站 2022-03-15 21:56:48
...

    服务端首先构造的是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即可。

相关标签: Android socket