![](/img/trans.png)
[英]Multi-client multi instance centralised server using TCP protocol gaming system in Java
[英]Setting up a multi-client/server TCP connection in Java
我正在嘗試用Java創建一個多客戶端/服務器應用程序。 我遇到了一些問題,因為我的線程似乎糾纏在一起......這就是我想要做的事情。
我有一個Server類,通過使用這段代碼接受客戶端:
while(true){Socket socket = serverSocket.accept(); }
我的服務器應該記住連接的客戶端,因此我使用該套接字創建一個名為ClientThread的新線程,並將該線程放在服務器上的列表中
該線程偵聽從客戶端發送的Command對象。 如果它收到命令,則需要將其發送到Server實例以進行進一步處理(不在該ClientThread上創建新的Server實例)。 我試圖通過在創建時將Server-instance添加到此Thread來實現此目的。 (這是正確的方法嗎?)
我的服務器也應該能夠隨時將對象發送回客戶端(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.