创建一个套接字服务器和客户端,允许通过线程和Java进行多个连接

时间:2015-06-01 11:06:56

标签: java multithreading sockets

我正在尝试创建一个简单的套接字服务器,以便通过多线程可以有多个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;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

到底发生了什么:

  1. 服务器创建ServerSocket并继续侦听客户端请求
  2. Client1 发送请求,服务器接受请求,创建 Reponder 对象并将其传递给单独的 MyServer 线程。
  3. 服务器开始在 ServerSocket &上侦听另一个客户端请求。该线程还等待来自 Client1 的输入。这导致线程锁定 Responder 对象。
  4. 新客户 Client2 连接到服务器。 ServerSocket 上接受请求,响应者的同一对象将传递到单独的线程以处理 Client2 请求。
  5. 请记住:通过thread1

    ,锁仍然保留在Responder对象上

    因此,除非 Client1 将某些数据发送到服务器,否则锁定将存在。服务器收到 Client1 数据后, thread2 对象即可用于 thread2 ,现在可以开始执行。

    但请坚持, Client1 仍然期望从服务器返回一些数据。因此,即使 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

    注意:如果有持续的客户端请求,服务器会不断回复,您的代码将完美无缺地工作。