最近Android項目中有需要用到Socket與服務器連接的項目,自己之前沒有使用過Socket套接字這種方案,所以對Socket通信機制就是個也很有限,領導在會議上講Socket通訊呢就是客戶端和服務器端先進行一次握手,雙方同意后就可以進行數據傳送。我心里最反感別人說這句話如果是大學老師第一次給我們講Socket概念的話,這話我樂意聽。對這有開發經驗的程序員竟然還這么跟我介紹Socket,我要的是方案的具體實施我不是問什么概念。C, bs一下。好了憤青完了該介紹項目中Socket通信的方案吧。
需求:1,一般Socket通信中服務器與客戶端的關系都是一對多關系的。而且需要附帶一個認證。
2,保證Socket長連接,網絡狀況是復雜的,不是單機演示Socket通信的demo。必須考慮到網絡沖斷的情況以及網絡防護墻問題。有人認為,我通過一個死循環去read就可以就這么簡單。實際上由于內外網防火墻的原因,Socket如果長時間不通信的話防火墻極有可能將其關閉。詳見轉載的關于socket長連接的心跳包。
心跳包:通信雙方為保證通信暢通(不被防火墻關閉)或者使對方及時知道是否已經斷線(一定時間內沒有收到心跳數據視為已經斷開)而定期給對方放送的某些特殊標識字符,這個字符可以根據雙方自定義。假設對方定義TimeOut時間為60秒則您應在在六十秒之前發送一個數據(心跳)給他,對方收到心跳后,心跳恢復Timeout回復到60秒。比如我們設定“/r/n”為心跳數據,那么我們可以利用TimeTask定期發送這個消息給對方。這樣心跳就完成了。例如服務器得到一個Socket socket.setKeepAlive(true); socket.setOOBInline(true);socket.setSoTimeout(40000);setSoTimeout就是定義心跳時間。如果40秒沒有收到任何消息就斷開。 在客戶段我們用這樣的代碼給他發心跳
[java] view plaincopy/** * 啟動心跳線程 */ PRivate void startHeartBeatThread() { // 啟動心跳線程 heartBeatTimer = new Timer(); heartBeatTask = new TimerTask() { @Override public void run() { // TODO Auto-generated method stub sendOrder("/r/n", false); } }; heartBeatTimer.schedule(heartBeatTask, 25000, 25000); } [java] view plaincopyprivate void sendOrder(String order){ try { outputStream.write(order.getBytes("UTF-8")); outputStream.flush(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } [java] view plaincopy這樣我們就完成心跳發送了新聞熱點
疑難解答