java - 如何使用套接字将数据从服务器发送到多个客户端?

标签 java multithreading sockets client server

我有简单的服务器-客户端程序:

public class Server extends Thread {
    private ServerSocket server;

    public Server(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            this.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            try {
                Socket client = server.accept();
                System.out.println(client.getInetAddress().getHostName()
                        + " connected");
                new ServerHandler(client);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

服务器处理程序必须在流中发送消息:

public class ServerHandler extends Thread {
    protected Socket client;
    protected String userInput;
    protected PrintWriter out;
    protected BufferedReader console;

    public ServerHandler(Socket client) {
        this.client = client;
        this.userInput = null;
        this.start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");
        System.out.println("Enter message:");
        try {
            this.out = new PrintWriter(client.getOutputStream(), true);
            this.console = new BufferedReader(new InputStreamReader(System.in));
            while ((this.userInput = console.readLine()) != null) {
                this.out.println(userInput);
            }               
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端收到该消息:

public class Client {
    protected Socket client;
    protected BufferedReader in;

    public Client(String hostName, int ip) {
        try {
            this.client = new Socket(hostName, ip);
            this.in = new BufferedReader(new InputStreamReader(
                    this.client.getInputStream()));
            String buffer = null;
            while ((buffer = in.readLine()) != null) {
                System.out.println(buffer);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

它适用于一个客户端,但是当我启动新客户端时,会出现从服务器接收消息的问题。 我做错了什么?

最佳答案

我找到了答案:

public class Server extends Thread {
    private ServerSocket server;
    protected List<ClientHandler> clients;

    public Server(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            clients = Collections
                    .synchronizedList(new ArrayList<ClientHandler>());
            this.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void run() {
        while (true) {
            try {
                Socket client = server.accept();
                System.out.println(client.getInetAddress().getHostName()
                        + " connected");
                ClientHandler newClient = new ClientHandler(client);
                clients.add(newClient);
                new SendMessage(clients);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

ClientHandler 而不是 Serverhandler 类:

public class ClientHandler {
    protected Socket client;
    protected PrintWriter out;

    public ClientHandler(Socket client) {
        this.client = client;
        try {
            this.out = new PrintWriter(client.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Thread 可以添加到 Client 类,但没有它也能正常工作。我假设是因为当调用 main 方法时自动创建了新线程:

public class Client {
    protected Socket client;
    protected BufferedReader in;

    public Client(String hostName, int ip) {
        try {
            this.client = new Socket(hostName, ip);
            this.in = new BufferedReader(new InputStreamReader(
                    this.client.getInputStream()));
            String buffer = null;
            while ((buffer = in.readLine()) != null) {
                System.out.println(buffer);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }       
}

向客户端发送数据的类:

 public class SendMessage extends Thread {
        protected List<ClientHandler> clients;
        protected String userInput;
        protected BufferedReader console;

        public SendMessage(List<ClientHandler> clients) {
            this.clients = clients;
            this.userInput = null;
            this.start();
        }

        public void run() {
            System.out.println("New Communication Thread Started");
            if (clients.size() == 1) {
                System.out.println("Enter message:");
            }
            try {
                if (clients.size() > 0) {
                    this.console = new BufferedReader(new InputStreamReader(
                            System.in));
                    while ((this.userInput = console.readLine()) != null) {
                        if (userInput != null & userInput.length() > 0) {
                            for (ClientHandler client : clients) {
                                client.out.println(userInput);
                                client.out.flush();
                            Thread.currentThread();
                            Thread.sleep(1 * 1000);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

现在可以了! 刷新数据后需要让 SendMessage 线程 hibernate 。 服务器启动器的主要内容:

public static void main(String[] args) {
new Server(1200);
}

主要用于客户端启动器:

public static void main(String[] args) {
new Client("127.233.0.1", 1200);
}

关于java - 如何使用套接字将数据从服务器发送到多个客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31786598/

相关文章:

java - Spring Boot fat jar 中出现 NoClassDefFoundError 但依赖项位于已编译的存档中,并且应用程序在 IDE 中运行良好

java向Web服务发送错误数据

java - 我可以将整数值附加到 stringbuilder 吗?

c++ - 如果信号线程被阻塞,为什么信号没有在接收线程中处理?

java - 使用 java 的 Websphere MQ SSL 连接

c++ - 监控一个线程的状态

java - 显示所有小于输入的素数的多线程程序

linux - 如果一台计算机更改了我们要向其发送数据的 IP 地址,TCP/IP 应该怎么做?

sockets - 如何控制Scala远程actor的TCP_NODELAY设置?

sockets - 通过多个套接字传输文件是否比仅使用一个套接字更快?