繁体   English   中英

处理多个客户端的流?

[英]Handle streams with multiple clients?

基本上我想做的是开发一个聊天程序(介于即时通讯程序和IRC之间)来提高我的Java技能。

但是到目前为止,我遇到了一个大问题:我不知道如果有多个客户端,如何正确设置流。 客户端与服务器之间的1:1聊天很容易进行,但是我不知道该怎么办,因此同一聊天中服务器可以与1个以上的客户端进行聊天。

这就是我得到的,但是我怀疑它会很有帮助,因为它只是往返于服务器的1个永久流。

private void connect() throws IOException {
        showMessage("Trying to connect \n");
        connection = new Socket(InetAddress.getByName(serverIP),27499);
        showMessage("connected to "+connection.getInetAddress().getHostName());

    }

    private void streams() throws IOException{
        output = new ObjectOutputStream(connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream(connection.getInputStream());
        showMessage("\n streams working");

    }

要从一个程序中读取多个流,您将必须使用多线程。 因为从流中读取是同步的,所以您需要为每个线程从一个流中读取。 有关多线程的更多信息,请参见线程Java教程

几个月前做了类似的事情。 基本上,我在每个客户端服务器端使用了单独的ServerSocketThread 当客户端连接时,您将该端口的输入和输出流注册到固定池中并阻塞,直到发送输入为止。 然后将输入复制到其他每个客户端并发送。 这是从命令行运行的基本程序:服务器代码:

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;

    public class ChatServer {

        static int PORT_NUMBER = 2012;

        public static void main(String[] args) throws IOException {


            while (true) {
                try (ServerSocket ss = new ServerSocket(PORT_NUMBER)) {
                    System.out.println("Server waiting @" + ss.getInetAddress());
                    Socket s = ss.accept();
                    System.out.println("connection from:" + s.getInetAddress());

                    new Worker(s).start();
                }
            }

        }

        static class Worker extends Thread {

            final static  ArrayList<PrintStream> os = new ArrayList(10);
            Socket clientSocket;
            BufferedReader fromClient;

            public Worker(Socket clientSocket) throws IOException {
                this.clientSocket = clientSocket;
                PrintStream toClient=new PrintStream(new BufferedOutputStream(this.clientSocket.getOutputStream()));
                toClient.println("connected to server");
                os.add(toClient);
                fromClient = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

            }
            @Override
            public void run() {

                while (true) {
                    try {
                        String message = fromClient.readLine();
                        synchronized (os) {


                            for (PrintStream toClient : os) {
                                toClient.println(message);
                                toClient.flush();
                            }
                        }

                    } catch (IOException ex) {
                        //user discnnected
                        try {
                            clientSocket.close();
                        } catch (IOException ex1) {

                        }
                    }

                }
            }
        }

}

客户代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class Client {

    public static void main(String[] args) throws IOException {

        final BufferedReader fromUser = new BufferedReader(new InputStreamReader(System.in));
        PrintStream toUser = System.out;
        BufferedReader fromServer;
        final PrintStream toServer;
        Socket s = null;

        System.out.println("Server IP Address?");


        String host;
        String port = "";


        host = fromUser.readLine();

        System.out.println("Server Port Number?");

        port = fromUser.readLine();

        s = new Socket(host, Integer.valueOf(port));

        int read;
        char[] buffer = new char[1024];


        fromServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
        toServer = new PrintStream(s.getOutputStream());
        new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        toServer.println(">>>" + fromUser.readLine());

                        toServer.flush();
                    } catch (IOException ex) {
                        System.err.println(ex);
                    }
                }
            }
        }.start();
        while (true) {
            while ((read = fromServer.read(buffer)) != -1) {
                toUser.print(String.valueOf(buffer, 0, read));
            }
            toUser.flush();

        }
    }
}

我已经使用ServerSocket(int port)Socket ServerSocket.accept()做了几次。 通过让它监听您希望聊天服务器客户端监听的一个端口,这可以非常简单。 主线程将阻止等待下一个客户端连接,然后将Socket对象返回给该特定客户端。 通常,您需要将它们放在一个列表中,以处理n个客户。

而且,是的,您可能要确保每个Socket处于不同的线程中,但这完全取决于程序员。

请记住,由于客户端使用不同的源端口(唯一的5元组(SrcIP,SrcPort,DstIP,DstIP,DstPort,TCP / UDP /其他IP协议)),因此无需重定向到服务器上的另一个端口将允许重用一个服务器端口。 因此,为什么我们都使用stackoverflow.com端口80。

编码愉快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM