2011-05-17 82 views
2

這是一個「進一步落後軌道」擴展到我剛纔問的一個問題...我現在對套接字有了更好的理解,並且有一些工作代碼,但需要改進它...如何將相同的數據發送到幾個使用TCP的android手機?

好的,所以我現在已經有了UDP多播工作機制,可以將短串文本從Java「服務器」應用程序發送到幾個Android手機(這可能會成爲幾百部Android手機)。這在大多數情況下都可以正常工作,但它確實傾向於在奇數手機上丟失奇怪的字符串,並隨機在短時間內完全丟失,而且沒有任何信息會傳遞給任何人,這可能有點令人沮喪。

因爲,據我所知,沒有辦法在TCP上進行廣播 - 我的想法是使用ServerSocket將手機最初連接到服務器應用程序。這隻會收穫客戶端IP地址,這些IP地址將被存儲在名爲的客戶端Set<InetAddress>中。然後,我將要遍歷這些地址並將字符串分別發送到每個電話 - 我不想阻止代碼,也不希望花費永遠等待發送發生,如果手機有去睡覺,不能/不會接受連接。這些信息需要在開始發送後幾秒鐘內到達所有電話(即使是2-300個客戶端也是如此)。

我最初的代碼如下,我已經把它的問題是:

  • 這段代碼在一個線程就夠了嗎?
  • 一個現代的CPU能夠很好地利用幾個線程,地址集在它們之間均勻分配(比如說4個線程?)
  • 是的(我相信)是一個不錯的主意,讓每個連接/自己發送線?
  • 設置套接字超時是否允許線程更快地處理其列表?或者這會導致問題?
  • 如果套接字超時設置是一個好主意,那麼什麼是合理的時間?或者我需要測試才能正確使用?

預先感謝任何幫助你們能提供...

for (InetAddress client : clients) { 
try { 
    Socket sendQuestionSocket = new Socket(client, portSend); 
    // Theory: 50 milliseconds is enough to connect, and could allow 200 clients 
    // to get their questions in around 10 seconds. Maybe? 
    sendQuestionSocket.setSoTimeout(50); 
    PrintWriter outStream = new PrintWriter(sendQuestionSocket.getOutputStream()); 
    outStream.println(question.toString()); 
    outStream.flush(); // Do I need this line? 
    sendQuestionSocket.close(); 
    outStream.close(); 
} catch (InterruptedIOException e) { 
    logger.log(Level.WARNING, "Couldn't connect in time... passing this one over"); 
    e.printStackTrace(); 
} catch (UnknownHostException e) { 
    logger.log(Level.SEVERE, "Unable to find that client"); 
    e.printStackTrace(); 
} catch (IOException e) { 
    logger.log(Level.SEVERE, "Unable to create question sending port"); 
    e.printStackTrace(); 
} 

}

+0

只是想知道如何管理髮送數據*到*電話,因爲他們的IP地址在互聯網上一般不可見。許多GSM提供商在專用網絡中都有他們的客戶並使用NAT(或類似的東西)。 – 2011-05-17 11:36:42

+0

嗨安德烈亞斯,手機連接到當地的WIFI網絡,它完全獨立於GSM網絡......嘗試在新西蘭使用GSM數據網絡將是非常昂貴的... – Steve 2011-05-17 21:03:46

回答

1

我會去與這裏的線程:一個線程爲每個客戶端。現代的CPU可以,它不會讓你阻止執行。所以,即使有很多死客戶,活的客戶也會盡快得到答案。

+0

謝謝你 - 我只是看了看周圍,發現這個線程:http://stackoverflow.com/questions/763579/how-many-threads-can-a-java-vm-support所以你可能就在那裏。當我今天有機會看到有多少連接線程可以運行到缺少客戶端,然後再進入「服務器」之前,我會給出一個答案......乾杯 – Steve 2011-05-17 21:15:02

1

我不確定你想要做的事情會起作用。 ServerSocket不允許您收集遠程IP地址,只需在需要時連接。爲了連接回這些設備,他們必須讓服務器監聽特定端口並接受您的傳入連接。

由於好像您已經有客戶端連接到您的服務器套接字,我只會告訴他們他們需要知道的任何連接之後 - 除非您真的可以在每部手機上都有服務器。

另一種選擇是使用(無連接)UDP,但客戶端代碼仍然需要主動等待數據報包。

在Java中做任何事情時,我都強烈建議Netty。 Netty將爲您處理所有異步網絡IO,並讓您專注於客戶端連接後要執行的操作。

+0

謝謝,但我不明白你的意思是由ServerSocket不在那裏讓我收集IP地址 - 它的工作原理是這樣的。客戶端實際上一直在積極監聽文本 - 我有一個接收器線程正在偵聽UDP多播數據包 - 但問題是如上所述的可靠性問題。我將看看Netty,但我將它用作Java網絡學習練習,因此用「黑盒子」代替我的網絡代碼對我來說並不理想。乾杯 – Steve 2011-05-17 21:06:23

+0

雖然你**可以**使用ServerSocket收集遠程地址,但這不是它的主要目的。爲什麼要建立一個TCP連接來收集遠程客戶端的IP地址?您已經在使用UDP回到「客戶端」電話。只需使用UDP進行服務器註冊步驟即可。 Netty不是黑匣子。它是一個放置在Java NIO類之上的Facade,用於隱藏我發現的Java NIO API的複雜性,難以使用。它非常強大,可以讓你非常容易地異步執行任務。使用它只是一個建議。 :) – alpian 2011-05-17 22:56:04

+0

感謝您的迴應......我正在使用它來確保客戶端應用程序正在與正確的服務器交談。它是一個認證系統的一部分,但還不完整......但它確保客戶端應用程序使用正確的端口進行偵聽,並瞭解服務器IP地址以發送響應。我已經開始閱讀Netty了,它看起來很有趣 - 我同意NIO - 我開始關注它,並放棄了一段時間:) – Steve 2011-05-18 05:45:03

相關問題