簡體   English   中英

創建一個套接字服務器和客戶端,以允許通過線程和Java進行多個連接

[英]Creating a socket server and client which allows multiple connections via threads and Java

我正在嘗試制作一個簡單的套接字服務器,以便它可以通過多線程具有多個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. 服務器創建ServerSocket並繼續偵聽客戶端請求
  2. Client1發送一個請求,服務器接受該請求,創建一個Reponder對象,並將其傳遞給單獨的MyServer線程。
  3. 服務器開始偵聽ServerSocket上的另一個客戶端請求,並且線程也等待來自Client1的輸入。 這導致線程在Responder對象上保持鎖定。
  4. 新客戶端Client2連接到服務器。 ServerSocket上接受了請求,並且Responder的相同對象被傳遞到單獨的線程來處理Client2請求。

切記:線程1仍將鎖鎖定在Responder對象上

因此,除非Client1服務器發送一些數據,否則該鎖將存在。 服務器接收到Client1數據后, 線程2即可使用Responder對象,現在可以開始執行了。

但是請稍等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

注意:考慮到連續不斷的客戶端請求,並且服務器不斷回復它們,您的代碼將可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM