簡體   English   中英

在Java中設置多客戶端/服務器TCP連接

[英]Setting up a multi-client/server TCP connection in Java

我正在嘗試用Java創建一個多客戶端/服務器應用程序。 我遇到了一些問題,因為我的線程似乎糾纏在一起......這就是我想要做的事情。

  1. 我有一個Server類,通過使用這段代碼接受客戶端:

    while(true){Socket socket = serverSocket.accept(); }

  2. 我的服務器應該記住連接的客戶端,因此我使用該套接字創建一個名為ClientThread的新線程,並將該線程放在服務器上的列表中

  3. 該線程偵聽從客戶端發送的Command對象。 如果它收到命令,則需要將其發送到Server實例以進行進一步處理(不在該ClientThread上創建新的Server實例)。 我試圖通過在創建時將Server-instance添加到此Thread來實現此目的。 (這是正確的方法嗎?)

  4. 我的服務器也應該能夠隨時將對象發送回客戶端(1個或更多)。 我試圖通過使用保存在ClientThread中的socket.getOutputStream()來完成此操作

我應該如何組織我的線程,以便每個客戶端始終監聽從服務器接受對象,並且他們可以隨時將對象發送到服務器。

我知道這不是一個特定的問題,但是如果你知道一些可能對這個用例有幫助的信息或教程,我會非常感激。

順便說一句:我知道如何創建套接字和發送(可序列化)對象等等。我只是堅持如何組織一切

你似乎糾結了線程和對象。 我會

a)確保你沒有在任何地方擴展Thread或調用你的對象XxxxThread。 使用ExecutorService來管理線程是個好主意。

b)具有用於響應客戶端命令的簡單模型,例如每個客戶端線程讀取任務然后執行任務。

c)為每個連接都有一個包裝器,例如使用sendMessage方法。

既然您已經了解套接字和線程,我就向您發送偽代碼的想法(案例需要特定部分代碼才能告訴我)

你沒有提到的一件事是如何通過其IP或任何其他方法(如ID)跟蹤客戶端? 任何給定的設備都可以使用不同的客戶端ID打開多個連接嗎? 或者你只能接受每個設備一個連接? 在任何情況下,如果客戶已經在列表中,您需要做什么? 你會把創建的線程傳遞給新套接字嗎? 你會破壞那個線程並創建一個新線程嗎? 或者你可能會忽略這個新請求?

這是我的想法(取自工作應用程序):

服務器准備服務器套接字並等待接受狀態。

一旦客戶端連接,服務器啟動一個線程來參加客戶端傳遞它剛剛使用accept命令創建的套接字。 ). 當訪問客戶端的線程啟動時,它從客戶端收到的第一條消息應該是密碼o特殊簽名,以便客戶端進入( )。

服務器代碼:

Prepares the server socket which listen in a well known port
Clear client list;

While (!Terminated)
{
      // if you want to impose a limit for connections, check it here:
      if (Is the list of connected client full?)
      {
           Sleep(reasonable time in seconds or miliseconds);
           continue;
       }
       ClientSocket = ServerSocket.Accept();
       if the client's IP is already in the list
       {
           depends on what you want to do.
       }
       else
       {
            Add client's IP to the list
            Start (create) new client Tread(ClientSocket);
       }
}
// when server finish
If (client list is not empty?)
{
   Kill all threads
   or
   Wait until all threads are done
   or
   Wait an amount of time and then kill those remaining.
}

線程客戶端代碼:

// This is optional, just to make sure a valid client is connected
Read packet from ClientSocket
if (!Is_the_passport_packet)
{
   close socket;
   return;
}

// if passport is not required, start here
Try
{
   While (!Terminated)
   {
      if (read packet from client);
      {
         switch (packet.Command)
         {
 // In your question you said you want the Server thread to process the request
 // I guess you have your requirements to do so,
 // anyway, you must use a mutex o some other synchronization method.
             case TASK_1:
                [sync] process TASK_1(packet, ClientSocket);
                break;
             case TASK_2:
                [sync] process TASK_2(packet, ClientSocket);
                break;
             etc ….

             case WORK_DONE:
                Close Socket;
                return;

             default:
                Log(received an unknown command: packet.command);
                break;

         }
      }
      else if (Client has quit (closed/broken socket))
      {
         // as you may know, a socket is consider shutdown when you received a 0 length data
         // and a broken connection when received -1 in either case all you have to do is
         Close Socket;
         return;
      }
  }
}
catch (Exception e)
{
    Log(received an exception: e.message);
}
finally
{
   Remove this client from the client's list
}

暫無
暫無

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

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