2010-01-16 87 views
1

有沒有一種方法可以實現爲客戶端串行服務的套接字服務器。
通常,實踐是將連接的客戶端分派到爲請求和響應提供服務的新線程,但是在服務器端每個客戶端有一個線程。串行服務客戶端的Java Socket服務器

我不想這樣做,因爲我後來想將此應用程序移植到Java ME,這可能會限制在某個時間點運行的併發線程數。

我想知道如何解決這個問題?

回答

4

當然,只是不發射後臺線程來處理客戶端。

編輯

好像你真正想要的是能夠連接大量的客戶端,但不能創建線程的負載。由於NIO似乎沒有被有關使用兩個線程如何支持:

  • 一個線程循環接受連接,通過連接的Socket到只是增加了它連接的套接字的列表,第二個線程(這必須是同步)
  • 第二個線程通過其活動連接的內部列表進行循環,並依次進行「一些工作」。

調用socket.setSoTimeout()的值相當小應該可以防止第二個線程在一個連接上等待太久。

+0

如何處理請求和響應,以及在其他客戶端想要連接時如何實現機制。服務器是否能夠將數據推送到客戶端,或者該設備在此機制下是否無法使用。 – 2010-01-16 00:40:29

+0

你說你想要連續處理連接 - 其他客戶端將無法連接。這不是你想要的嗎? – Draemon 2010-01-16 00:44:58

+0

我的印象是,一旦你聽到客戶端將排隊到本地tcp堆棧的限制,並且使用accept將它們從堆棧中拉出來。其他客戶端將能夠連接,但直到服務器處理每個人之前都不會收到數據。 – Jherico 2010-01-16 00:48:26

1

通常服務器處理看起來是這樣的:

ServerSocket s; 
    Socket newSocket; 
    while (newSocket = s.accept()) { 
     new SocketHandlingThread(newSocket).start(); 
    } 

其中SocketHandlingThread()是您創建做一個類無論插座談話的服務器端應該是。

有兩種基本的方法可以做你正在問的問題(即同步處理插座)。首先是重新搬回到接受(),這樣

while (newSocket = s.accept()) { 
     SocketHandlingThread thread = new SocketHandlingThread(newSocket); 
     thread.start(); 
     thread.join(); 
    } 

正如下面的評論中指出之前的處理器線程上簡單地加入,可以在避免只調用像線程的run方法的加入所以

thread.run(); 

代替開始和加入呼叫。

另一種方法是採取SocketHandlingThread的run方法中的任何代碼並將其直接移入循環。

+0

我認爲你的意思是thread.start()不是thread.run(),你可以通過調用thread.run()來實現你的第二個方法 - 不需要thread.join() – Draemon 2010-01-16 00:43:28

+0

指出固定錯誤。 – Jherico 2010-01-16 00:46:37

+0

加入會導致調用進程在返回之前等待您加入的線程完成。它基本上是一個'等到這件事完成'的功能。 – Jherico 2010-01-16 00:47:21

1

您可以使用非阻塞套接字。如果你這樣做,那麼你不需要每個客戶端的線程。 Java已經通過NIO支持了一段時間。我不確定這是否受Java ME支持。 Java ME現在正在成長,因此它包含了JSE的許多功能。在需要服務許多客戶端連接的Java ME環境中具有服務器端功能可能有點不尋常。

在你的情況下,流量是否仍然不通過服務器路由?如果是這樣,沒有理由說J2ME環境無法通過單個套接字連接到服務器來接收來自許多其他客戶端或對等方的消息(如果您想調用它們)。

+0

對於p2p聊天應用程序,我需要實現這種機制。對不起,說J2ME不支持NIO。 – 2010-01-16 00:47:29

+0

在這種情況下,沒有服務器是一臺電話充當服務器。 – 2010-01-16 02:43:00

+0

你的客戶如何發現手機的IP地址和端口? – 2010-01-16 02:47:12

0

您可以在接受套接字上設置SO_TIMEOUT。這將強制接受呼叫是非阻塞的。這樣你就可以等待一段時間,然後服務一個以前接受的連接,然後回到接受新的連接,等等。該代碼會隱約看起來像這樣:

do(
    try{ 
    socket.setSoTimeout(200); 
    Socket connected = socket.accept() 
    } catch (SocketTimeoutException e){//just ignore} 
    //handle your other threads/connections here 
} while (!shutDown) 
+0

你能詳細說一下嗎? – 2010-01-16 00:53:03

+0

添加代碼到原來的帖子來說明 – malaverdiere 2010-01-29 13:54:10

+0

它會強制它阻塞超時。這與非阻塞不同。 – EJP 2015-11-25 12:08:45

1

還有就是服務器端的socket處理包括資源池,可以發現here一個很好的例子。

然而,考慮一下,你可能並不需要池 - 我從一臺服務器爲每個服務800個併發客戶端都有自己的專用套接字線程沒有問題。

+0

將檢查鏈接,800線程看起來相當不錯,這裏的問題是我想將代碼移植到Java ME,並且它可能有問題,甚至有5個併發線程。我試圖在這裏用所有的手機玩這個遊戲。 – 2010-01-16 01:49:36

+1

啊,對不起,我以爲你的意思是你有很多ME客戶端連接到你控制的服務器。我在ME上支持的最小支持線程的快速谷歌發現以下內容:http://discussion.forum.nokia.com/forum/showthread.php?t=79232 您是否想過通過中央服務器傳遞所有通信?由於沙盒限制,我會認爲這樣做必須這樣做,但是我已經碰到了Java ME很長一段時間了! – Pool 2010-01-16 01:58:53

+0

我已經給了它一個想法,但現在我不能通過該實現,非常感謝這個鏈接,這確實是非常有用的,它給了我一些線索什麼新的文檔挖掘和檢查新的線程規格。那麼J2ME平臺有一些限制,但它已經有了很大的改進。希望我能給你+2。乾杯! – 2010-01-16 02:16:52