[英]Java help creating a new socket per connected user
我正在創建一個聊天服務器,但無法建立多個連接,我相信這是因為只有一個套接字。 我讀過,一個線程一次可以處理多個套接字連接,但是每個客戶端必須擁有自己的套接字。 像牆上的插座。 每個插頭必須有1個插座。 如何為每個客戶端創建用於與服務器通信的套接字? 我將提供一些代碼來幫助你們以幫助為基礎。 這是接受單個套接字(連接)的地方。
private void waitForConnection() throws IOException
{
connection = server.accept();
showMessage("\nNow connected to " + connection.getInetAddress().toString());
clientCount += 1;
}
這是從服務器啟動處調用代碼的位置:
public void startRunning()
{
try
{
server = new ServerSocket(1337, 10);
while(true)
{
try
{
showMessage("Waiting For a Player To Connect...");
waitForConnection();
setupStreams();
whileChatting();
}
catch(EOFException eofException)
{
showMessage("\n Server ended the connection! ");
}
finally
{
closeConnections();
}
}
}
catch(IOException ioException)
{
ioException.printStackTrace();
}
}
現在,此代碼對於第一個已連接的客戶端非常有效。 所有其他人根本無法連接。 在此先感謝所有提交答案的人。
您應該讓一個線程始終執行socket.accept()
。 那是:
socket.accept()
)時,都應該
Thread
,從現在開始將負責該客戶端。 (我將這個Thread
稱為擴展類ClientNanny
); socket.accept()
。 這是您的waitForConnection()
方法的外觀:
private List<ClientNanny> clients = new ArrayList<ClientNanny>();
private void waitForConnection() throws IOException
{
while (true) { /* or some other condition you wish */
connection = server.accept(); /* will wait here */
/* this code is executed when a client connects... */
showMessage("\nNow connected to "
+ connection.getInetAddress().toString());
ClientNanny nanny = new ClientNanny(connection); /* call a nanny to take
care of it */
clients.add(nanny); /* make sure you keep a ref to it, just in case */
nanny.start(); /* tell nanny to get to work as an independent thread */
clientCount += 1; /* you dont need this: use clients.size() now */
}
}
如果您沒有注意到, ClientNanny
應該類似於:
class ClientNanny extends Thread {
ClientNanny(Socket baby) {
this.myBaby = baby;
}
@Override
public void run() {
bed.put(myBaby); /* and probably other commands :) */
}
}
現在,您應該注意到下面突出顯示的代碼...
try
{
showMessage("Waiting For a Player To Connect...");
waitForConnection();
setupStreams(); /* <--------- THIS LINE! HI! I'M A HIGHLIGHT! */
whileChatting(); /* <--------- THIS LINE! HI! I'M A HIGHLIGHT TOO! */
}
當您按照我的建議更改waitForConnection()
時,將不會執行(因為waitForConnection()
將在while(true)
循環內不斷滾動)。 也許您可以將socket.accept()
放在其自己的線程上...無論如何,我相信您可以從現在開始使用它,是嗎?
PS .:作為最終指針,上述解決方案使用new Thread()
(或與此相關的new ClientNanny()
),因為這是解釋問題的最簡單方法。 但是,非常理想的解決方案可能涉及使用ExecutorService
(大致是線程池),正如在此答案中迅速指出的那樣。
您的代碼的整個結構是錯誤的:
waitForConnection();
setupStreams();
whileChatting();
這不能滿足您的要求。 您的循環應該不做任何事情,只接受連接,然后為處理該套接字上所有I / O的每個線程啟動一個新線程。 請參閱Java教程的“ 定制網絡”部分。
您的套接字代碼應類似於以下PSEUDO-CODE:
create server socket
while true (or quit received) {
accept connection
spawn thread to handle communication
}
也就是說,您需要為每個連接生成一個線程。 然后, 每個線程都可以執行whileChatting() ,而不用占用主線程。
例:
while (true) {
try {
// listen for client connections
Socket s = svr.accept();
// start a separate thread to handle this client's communications
new ChatClientHandler(s).start();
}
catch (IOException e) {
// print out the error, but continue!
System.err.println(e);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.