2011-03-08 34 views
1

我正在做一個類的項目,我們正在創建一個可以在局域網上使用2-4個玩家的遊戲。儘管我們的小組成員都沒有做過任何Java聯網,但是我們卻愚蠢地認定它不會很難搞清楚。無論如何,讓網絡工作的工作落到了我的頭上,但我完全失去了如何去做。我找不到任何在線教程,除了真正基本的東西,如從單個客戶端傳遞字符串到服務器。所以我有幾個問題。在我的腦海中與Java聯網

首先,如何將多個客戶端連接到服務器。我是否需要爲每個創建一個新的ServerSocket

其次,有沒有任何易於使用的庫,可以抽象出一些這樣的我?

我知道這些可能是非常基本的問題,但我真的已經做了一些閱讀,我仍然沒有得到任何地方。

回答

1

由於這是一個學習練習,我建議不要嘗試在基本套接字API之上找到一個庫。每個Java開發者都應該知道這些東西的工作原理

您在服務器端創建一個ServerSocket以偵聽端口上的傳入連接。坐在等待連接的循環中。當您連接到客戶端時,最簡單的方法是啓動一個線程來管理該連接。線程在客戶端關閉連接時終止(或者存在io錯誤 - 連接斷開)。

然後你需要設計在線協議。通常,您需要用4個字節(int)來表示請求類型。然後根據請求類型解釋其餘部分。編碼字符串時,決定是要使用基於長度的編碼還是基於終止符的編碼。

其實通過鍛鍊這個東西真正起作用將是非常有教育意義的練習。

+2

這可能會幫助你開始:http://oreilly.com/catalog/javanp2/chapter/ch11.html – 2011-03-08 20:54:48

+0

我通常會同意你的看法,我應該做我自己,而不是使用一個庫,但該類是關於軟件工程而不是直接編程的。我只有幾個星期的時間來完成這個項目,而網絡只是項目的一小部分,所以我需要儘快完成。另外,我正在上學期的學期,我已經爲一家.NET商店的公司找到了一份工作,所以我現在還不瞭解Java網絡的複雜性。 – rybl 2011-03-08 21:06:59

+2

無論您使用哪種語言,基本聯網主體都是相同的。即使你不認爲你會直接利用這些技能,但瞭解這些東西的工作原理仍然非常有用。如果你真的想避免學習這一點,看看Java RPC(遠程過程調用)。如果您的通信需求很小(消息類型的數量),則無法保證以這種方式節省大量時間。不用學習套接字,而是學習RPC或其他消息抽象庫。 – 2011-03-08 21:16:02

2

Akkaremote actors可能會有所幫助。這是一個基本的客戶端 - 服務器連接的例子:

// server code 
class HelloWorldActor extends UntypedActor { 
    public void onReceive(Object msg) { 
     getContext().replySafe(msg + " World"); 
    } 
} 
remote().start("localhost", 9999).register(
    "hello-service", 
    actorOf(HelloWorldActor.class)); 

// client code 
ActorRef actor = remote().actorFor(
    "hello-service", "localhost", 9999); 
Object res = actor.sendRequestReply("Hello"); 

阿卡確實提高抽象層次,很像RPC,所以這看上去好像你只是本地對象進行交互。它也將有助於併發性和可伸縮性,但在您的情況下,這些可能不是那麼重要。

1

雖然我完全同意康斯坦丁你應該至少使用一次純套接字,但你確實提到這是一個軟件工程課程,我認爲你不應該重新創建另一個網絡庫,而不必重新編寫你的應用代碼。

如果你想要一個庫,Apache MinaNetty是兩個用於分佈式網絡的基於Java的框架。

我之前使用過Mina,它將一些低級套接字複雜性抽象爲更多事件驅動的框架。使用時間服務器示例查看this快速入門指南,並注意MinaTimeServer和TimeServerHandler類的簡單性。只需在您的處理程序中創建一個會話,然後在MessageReceived()中放入您需要的任何邏輯。你將不必處理字節數組或字符串的編碼等。

我沒有Netty的經驗,所以我不會對此發表評論。

1
class ServerListener extends Thread { 
    ServerListener() { 
    this.serverSocket = new ServerSocket(53123); // port number, best to use btw 10000 and 65000 
    } 
    public void run() { 
    while(true) { 
     Socket s = serverSocket.accept(); 
     // the previous line blocks until an actual client connects 
     new ClientCommunicator(s).start(); 
    } 
    } 
} 
class ClientCommunicator extends Thread { 
    public void run() { 
    while (true) { 
     try { 
     Message msg = s.read(); 
     processMessage(msg); 
     } catch (IOException ex) { 
     // connection broke - kill this client 
     clientManager.killClient(this); 
     } 
    } 
    } 
} 
class Client { 
    Client() { 
    Socket s = new Socket ("localhost", 53123); // use the same port number 
    // now start sending messages to the socket/reading messages from it 
    } 
} 
相關問題