2013-02-12 52 views
4
我有一點麻煩

多客戶,現在我已經看過這個教程 http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html 本教程爲您提供了多個客戶端可以連接到,當他們連接到他們被告知該服務器的服務器隨着一個敲門工作,現在我明白如何傳輸數據,什麼不是,但線程是如何工作的?服務器通過螺紋

我正在一個網絡pong遊戲中,服務器將持有這些職位並將它們傳遞給客戶端,現在我有一個客戶端連接到服務器,並且球位置傳遞給客戶端,工作正常,有點跳動,但我確定一個帶有.sleep的線程會有所幫助。但無論如何,我的問題是,我如何讓我的客戶端成爲一個線程?我如何儲存它們?

例如這裏是磕磕服務器多線程類

package knockKnockServer; 

import java.net.*; 
import java.io.*; 

public class KKMultiServerThread extends Thread { 
private Socket socket = null; 

public KKMultiServerThread(Socket socket) { 
super("KKMultiServerThread"); 
this.socket = socket; 
} 

public void run() { 

try { 
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(
       new InputStreamReader(
       socket.getInputStream())); 

    String inputLine, outputLine; 
    KnockKnockProtocol kkp = new KnockKnockProtocol(); 
    outputLine = kkp.processInput(null); 
    out.println(outputLine); 

    while ((inputLine = in.readLine()) != null) { 
    outputLine = kkp.processInput(inputLine); 
    out.println(outputLine); 
    if (outputLine.equals("Bye")) 
     break; 
    } 
    out.close(); 
    in.close(); 
    socket.close(); 

} catch (IOException e) { 
    e.printStackTrace(); 
} 
} 
} 

在這裏,在服務器上我們有

package knockKnockServer; 

import java.net.*; 
import java.io.*; 

public class MultiKKServer { 
public static void main(String[] args) throws IOException { 
    ServerSocket serverSocket = null; 
    boolean listening = true; 

    try { 
     serverSocket = new ServerSocket(4444); 
    } catch (IOException e) { 
     System.err.println("Could not listen on port: 4444."); 
     System.exit(-1); 
    } 

    while (listening) 
    new KKMultiServerThread(serverSocket.accept()).start(); 

    serverSocket.close(); 
} 
} 

現在看看服務器將每個連接上創建一個新的KKMultiServerThread,但我如何儲存它們?我可以創建一個KKMultiServerThread數組嗎? 我試圖讓KKMultiServerThread 數組,當我嘗試這條線

multi[0] = new KKMultiServerThread(serverSocket.accept()).start(); 

我得到這個錯誤「無法轉換無效主題」 如果任何人都可以照我的問題有些光這將是巨大的。

帆布

更新

我現在有自己的線程類

package Pong; 

import java.net.*; 
import java.io.*; 

public class PongPlayerThread extends Thread 
{ 
private Socket socket = null; 
private String pongData = ""; 

public PongPlayerThread(Socket socket, int id) 
{ 
    super("PongPlayerThread"); 
    this.socket = socket; 
} 

public void passData(String data) 
{ 
    pongData = data; 
} 

public void run() 
{ 
    try 
    { 
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
     while(true) 
     { 
      out.println(pongData); 
     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

} 

的pongData是凝聚在一起字符串中的所有信息,現在如果我宣佈在PLAYER1字符串我的乒乓服務器的頂部像這樣

private static PongPlayerThread player1; 

and do th是當它是聽

while(listen) 
    { 
     PongPlayerThread player1 = new PongPlayerThread(serverSocket.accept(), 0).start(); 
    } 

它給了我這個錯誤「無法從空轉變爲PongPlayerThread」如何解決這一行?

回答

0

你的數組聲明中缺少對象類型

KKMultiServerThread multi[0] = new KKMultiServerThread(serverSocket.accept()).start(); 

何苦關係嗎?除非線程需要彼此通信,否則讓線程自由運行是可以的。就服務器而言,Run()方法定義套接字的整個生命週期。每個線程都有一個遊戲狀態的獨立副本(只要你不使用靜態),並且會在沒有任何額外干預的情況下快樂地與客戶端進行通信。

這是一個Java中的Socket/Thread庫對你有利的情況,除非你有特定的需求,否則不要使它更復雜。

+0

確定這裏還有另一個問題,當一個客戶端連接第一個客戶端需要能夠控制屏幕右側的蝙蝠時,第二個客戶端需要控制屏幕的左側蝙蝠,我怎麼知道哪個客戶端是哪一個? 此外,你給我的線說KKMultiServerThread不能解析爲變量 – Canvas 2013-02-12 17:56:53

+0

你可以創建特定的線程實例像player1(左)和player2(右),並更改服務器只接受兩個連接,然後再停止監聽。然後玩家的代碼有一個簡單的標誌,告訴它它應該是哪一邊。 – 2013-02-12 17:59:33

+0

我會怎麼做呢? – Canvas 2013-02-12 18:01:10

0

當客戶端連接到服務器時。服務器通常會爲該客戶端專門創建一個新線程。以下是一些僞代碼:

WHILE SERVER IS RUNNING 

SERVER WAITS FOR A CLIENT TO CONNECT 
SERVER ACCEPTS THE CLIENT IF THERE IS ENOUGH MEMORY TO CREATE A NEW THREAD 
SERVER CREATES A NEW THREAD ROUTINE FOR THE CLIENT PASSING THE CLIENT INFORMATION TO THE THREAD 
SERVER CONTINUES TO LISTEN WHILE EACH THREAD IS SPECIFICALLY TAILORED FOR THE CLIENTS 

REPEAT 

您問過需要採取哪些步驟來減少延遲?對於初學者來說,設置一個最大允許的連接。你不希望5000個客戶擁有自己的線程。除非你的機器能夠處理所有這些並且仍然運行。使用UDP而不是TCP,並且數據壓縮儘量減少帶寬,一次不會發送50GB的信息;如果你只需要幾個字節的信息就可以發送。嘗試發送不是字符串而是字節的位置信息。例如,您可以將位置X = 5Y = 0發送爲50,並將第一個十進制數字解析爲X,將第二個十進制數字解析爲Y.

而不是在線程例程中傳遞客戶端套接字,客戶。由於Pong是兩個玩家限制與兩個客戶的連接。0玩家1和1球員2.所以

new KKMultiServerThread(clientID).start(); // clientID is of type int 

編輯:

int id = 0; 
while(serverIsRunning) 
{ 
    Client client = server.accept(); 
    if (id > 2) client.Close(); // Do not accept. 
    Thread.New(id).Start(); 
    id++; 
} 
+0

乒乓遊戲需要先在TCP/IP然後UDP:D – Canvas 2013-02-12 17:57:25

+0

好吧,我會抓取UDP部分。 – 2013-02-12 17:58:11

+0

好吧,所以構造函數接受一個int爲其clientID,但對於輸入如何檢查它的ID? new KKMultiServerThread(clientID).start(); // clientID的類型是int 但是我的構造函數被賦予了一個套接字?它應該採用socket和clientID嗎? – Canvas 2013-02-12 18:08:14