【Socket】关于socket长连接的心跳包
TCP的socket本身就是長(zhǎng)連接的,那么為什么還要心跳包呢??
在smack里有個(gè)30s發(fā)送一個(gè)空消息的線程,同樣關(guān)于心跳包(keepalive)
據(jù)網(wǎng)絡(luò)搜索到的資料解釋如下
以前開(kāi)發(fā)手機(jī)游戲時(shí),索愛(ài)有一款手機(jī)有強(qiáng)制要求,客戶端如果超過(guò)三分鐘無(wú)消息發(fā)向網(wǎng)絡(luò)服務(wù)端,則會(huì)在客戶端自動(dòng)地強(qiáng)制把socket關(guān)斷。因?yàn)閟ocket長(zhǎng)連接相對(duì)于手機(jī)這樣資源少的設(shè)備來(lái)說(shuō)是寶貴的資源。? (這個(gè)強(qiáng)制是指客戶端系統(tǒng)自動(dòng)關(guān)的,不是我們代碼close的)?
以下是Smack里發(fā)送心跳包的代碼:PacketWrite.java
void startKeepAliveProcess() { int keepAliveInterval = SmackConfiguration.getKeepAliveInterval(); if (keepAliveInterval > 0) { KeepAliveTask task = new KeepAliveTask(keepAliveInterval); this.keepAliveThread = new Thread(task); task.setThread(this.keepAliveThread); this.keepAliveThread.setDaemon(true); this.keepAliveThread.setName("Smack Keep Alive (" + this.connection.connectionCounterValue + ")"); this.keepAliveThread.start(); } } private class KeepAliveTask implements Runnable { private int delay; private Thread thread; public KeepAliveTask(int paramInt) { this.delay = paramInt; } protected void setThread(Thread thread) { this.thread = thread; } public void run() { try { Thread.sleep(15000L); } catch (InterruptedException localInterruptedException) { } while ((!(PacketWriter.this.done)) && (PacketWriter.this.keepAliveThread == this.thread)) { synchronized (PacketWriter.this.writer) { if (System.currentTimeMillis() - PacketWriter.this.lastActive >= this.delay) { try { PacketWriter.this.writer.write(" "); PacketWriter.this.writer.flush(); } catch (Exception localException) { } } } try { Thread.sleep(this.delay); } catch (InterruptedException localInterruptedException1) { } } } } View Code? 另外記一個(gè)CSDN上早些年的問(wèn)題:
我還是很有發(fā)言權(quán)的呀,我畢業(yè)設(shè)計(jì)就是寫(xiě)的這個(gè)(不過(guò)當(dāng)時(shí)用的是vc寫(xiě)的,帶文件傳輸?shù)?#xff09;@hl_ghost
我來(lái)說(shuō)下我的思路吧:
1.如何知道誰(shuí)在線?
??????Server維護(hù)一個(gè)list就ok了(存所有人的ip,名字,在線等)
2.如何讓服務(wù)器隨時(shí)能找到你?
???前提:內(nèi)網(wǎng)機(jī)器如果不主動(dòng)向外發(fā)起連接,外網(wǎng)機(jī)沒(méi)法直連內(nèi)網(wǎng)的,這也是內(nèi)網(wǎng)機(jī)安全的原因之一吧,又因?yàn)槁酚善鲿?huì)把這個(gè)關(guān)系記錄下來(lái),但是過(guò)一段時(shí)間這個(gè)記錄可能會(huì)丟失?,所有每一個(gè)客戶端 ? ?每隔一定時(shí)間就會(huì)向服務(wù)器發(fā)送消息,以保證服務(wù)器可以隨時(shí)找到你,這東西被稱為心跳包。
3.如何跨內(nèi)網(wǎng)直連
???Nat打洞(難):
???我簡(jiǎn)單說(shuō)下原理,有兩個(gè)客戶端A,B?,當(dāng)然必須有Server啦(他可以隨時(shí)連接A,B)
???當(dāng)A想連B時(shí),A就回從Server那要B的ip,然后與B建立連接(第一次不能成功的,因?yàn)榭醇t字)。
???這時(shí)A告訴Server,我找不到B,你替我告訴他一聲,我想與它連接,服務(wù)器就告訴B,你給A下一個(gè)請(qǐng)?zhí)?#xff08;B發(fā)請(qǐng)求向A)!?
???這時(shí)A再向B發(fā)起連接就可以成功了(以后就不用server幫忙了)。
4.如何保證數(shù)據(jù)的可靠性(難)
???滑動(dòng)窗口協(xié)議,這個(gè)一句話兩句說(shuō)不清楚啦,自己google下。
5是否在線。
?????我的設(shè)計(jì)是每隔40秒客戶端把Server中存自己的信息中的在線改為真,而服務(wù)器每過(guò)45秒就檢查這個(gè)在線變量是否為真,真的話把他改成假,如果假的話就說(shuō)明這個(gè)人在45秒沒(méi)有向Server報(bào)到=>他網(wǎng)絡(luò)出現(xiàn)異常了,掉線了,向其它人發(fā)這個(gè)人的掉線通知。(這么設(shè)計(jì)原因在于當(dāng)用戶網(wǎng)斷了沒(méi)有發(fā)下線通知,我們也能知道他不在線了)
6文件傳輸(難)
???把文件讀到buf里,然后每次發(fā)1024b(當(dāng)收到接收方確認(rèn)后再發(fā)下一個(gè)1024b)。
?
參考文章
http://www.cppblog.com/tx7do/archive/2009/11/09/100513.html
http://bbs.csdn.net/topics/270063434
?
轉(zhuǎn)載于:https://www.cnblogs.com/lcw/p/3565459.html
總結(jié)
以上是生活随笔為你收集整理的【Socket】关于socket长连接的心跳包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 注意Entity中的Uptate
- 下一篇: BZOJ2081 [Poi2010]Be