【问题标题】:Creating a socket server and client which allows multiple connections via threads and Java创建允许通过线程和 Java 进行多个连接的套接字服务器和客户端
【发布时间】:2015-06-01 20:28:09
【问题描述】:

我正在尝试制作一个简单的套接字服务器,以便它可以通过多线程进行多个 TCP 连接,但我似乎无法让它工作。它适用于 1 个客户端,但我无法连接另一个客户端。我是新手,任何帮助将不胜感激。

public class Client {

public static void main(String argv[]) throws Exception {
    String sentence;
    String modifiedSentence;

    BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost", 6789);

    while (true) {
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        sentence = inFromUser.readLine();
        outToServer.writeBytes(sentence + '\n');
        if (sentence.equalsIgnoreCase("EXIT")) 
        {
            break;
        }
        else if (sentence.equalsIgnoreCase("i am the boss"))
        {
            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
            Thread.currentThread().setName("boss");
            System.out.println("You have top priority boss");
        }
        else if(sentence!=null)
        {
            System.out.println("running thread name is:"+Thread.currentThread().getName());  
            System.out.println("running thread priority is:"+Thread.currentThread().getPriority());  
        }
        modifiedSentence = inFromServer.readLine();
        System.out.println("server : " + modifiedSentence);
    }
    clientSocket.close();
}


public class Server {

    public static void main(String argv[]) throws Exception {

        ServerSocket welcomeSocket = new ServerSocket(6789);
        Responder h = new Responder();
        while (true) {

            Socket connectionSocket = welcomeSocket.accept();
            Thread t = new Thread(new MyServer(h, connectionSocket));

            t.start();
        }
    }
}

class MyServer implements Runnable {

        Responder h;
        Socket connectionSocket;

        public MyServer(Responder h, Socket connectionSocket) {
            this.h = h;
            this.connectionSocket = connectionSocket;
        }

        @Override
        public void run() {

            while (h.responderMethod(connectionSocket)) {
                try 
                {
                    Thread.sleep(5);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }

            try {
                connectionSocket.close();
            } catch (IOException ex) {
                Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

}

class Responder {

    String serverSentence;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    synchronized public boolean responderMethod(Socket connectionSocket) {
        try {
            BufferedReader inFromClient =new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream outToClient =  new DataOutputStream(connectionSocket.getOutputStream());
            String clientSentence = inFromClient.readLine();

            if (clientSentence.equalsIgnoreCase("EXIT")) {
                return false;
            }

            if (clientSentence != null) {
                System.out.println("client : " + clientSentence );


            }

            serverSentence = br.readLine() + "\n";
            outToClient.writeBytes(serverSentence);
            return true;

        } catch (SocketException e) {
            System.out.println("Disconnected");
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

【问题讨论】:

  • 您在尝试启动另一个客户端时是否收到错误消息?如果有,是什么?

标签: java multithreading sockets


【解决方案1】:

到底发生了什么:

  1. 服务器创建 ServerSocket 并持续监听客户端请求
  2. Client1 发送请求,服务器接受它,创建 Reponder 对象并将其传递给单独的 MyServer 线程。李>
  3. 服务器开始在 ServerSocket 上侦听另一个客户端请求,并且线程还等待来自 Client1 的输入。这会导致线程持有 Responder 对象的锁。
  4. 新客户端 Client2 连接到服务器。 ServerSocket 接受请求,Responder 的同一对象被传递给单独的线程来处理 Client2 请求。

记住:线程1仍然持有Responder对象上的锁

因此,除非Client1Server 发送一些数据,否则锁将存在。一旦服务器接收到 Client1 数据,Responder 对象就可供 thread2 使用,现在就可以开始执行了。

但请稍等,Client1 仍希望从 Server 返回一些数据。因此,即使 Client2 将其数据发送到服务器,服务器也不会回复它,除非它先回复 Client1

这会导致一次只观察到单个客户端-服务器通信的情况。


或者,您可以创建响应者类的单独对象来处理每个客户端请求。

您可以将分隔语句(如下)放在 while 循环中:

public class Server {

    public static void main(String argv[]) throws Exception {

        ServerSocket welcomeSocket = new ServerSocket(6789);

        Responder h = new Responder();

        while (true) {

            Socket connectionSocket = welcomeSocket.accept();
            Thread t = new Thread(new MyServer(h, connectionSocket));

            t.start();
        }
    } }

这将为每个客户端请求创建一个单独的响应器,最终多个客户端请求将由服务器处理,并且也是可观察的。 :D

注意:您的代码将完美运行,因为有持续的客户端请求,并且服务器不断回复它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多