網(wǎng)絡(luò)聊天程序的三種模式
實(shí)現(xiàn)一個(gè)網(wǎng)絡(luò)聊天程序本應(yīng)是最后一篇文章的內(nèi)容,也是本系列最后的一個(gè)程序,來(lái)作為一個(gè)終結(jié)。但是我想后面更多的是編碼,講述的內(nèi)容應(yīng)該不會(huì)太多,所以還是把講述的東西都放到這里吧。
當(dāng)采用這種模式時(shí),即是所謂的完全點(diǎn)對(duì)點(diǎn)模式,此時(shí)每臺(tái)計(jì)算機(jī)本身也是服務(wù)器,因?yàn)樗枰M(jìn)行端口的偵聽(tīng)。實(shí)現(xiàn)這個(gè)模式的難點(diǎn)是:各個(gè)主機(jī)(或終端)之間如何知道其它主機(jī)的存在?此時(shí)通常的做法是當(dāng)某一主機(jī)上線時(shí),使用UDP協(xié)議進(jìn)行一個(gè)廣播(Broadcast),通過(guò)這種方式來(lái)“告知”其它主機(jī)自己已經(jīng)在線并說(shuō)明位置,收到廣播的主機(jī)發(fā)回一個(gè)應(yīng)答,此時(shí)主機(jī)便知道其他主機(jī)的存在。這種方式我個(gè)人并不喜歡,但在 C#編寫(xiě)簡(jiǎn)單的聊天程序 這篇文章中,我使用了這種模式,可惜的是我沒(méi)有實(shí)現(xiàn)廣播,所以還很不完善。
?第二種方式較好的解決了上面的問(wèn)題,它引入了服務(wù)器,由這個(gè)服務(wù)器來(lái)專(zhuān)門(mén)進(jìn)行廣播。服務(wù)器持續(xù)保持對(duì)端口的偵聽(tīng)狀態(tài),每當(dāng)有主機(jī)上線時(shí),首先連接至服務(wù)器,服務(wù)器收到連接后,將該主機(jī)的位置(地址和端口號(hào))發(fā)往其他在線主機(jī)(綠色箭頭標(biāo)識(shí))。這樣其他主機(jī)便知道該主機(jī)已上線,并知道其所在位置,從而可以進(jìn)行連接和對(duì)話。在服務(wù)器進(jìn)行了廣播之后,因?yàn)楦鱾€(gè)主機(jī)已經(jīng)知道了其他主機(jī)的位置,因此主機(jī)之間的對(duì)話就不再通過(guò)服務(wù)器(黑色箭頭表示),而是直接進(jìn)行連接。因此,使用這種模式時(shí),各個(gè)主機(jī)依然需要保持對(duì)端口的偵聽(tīng)。在某臺(tái)主機(jī)離線時(shí),與登錄時(shí)的模式類(lèi)似,服務(wù)器會(huì)收到通知,然后轉(zhuǎn)告給其他的主機(jī)。
第三種模式是我覺(jué)得最簡(jiǎn)單也最實(shí)用的一種,主機(jī)的登錄與離線與第二種模式相同。注意到每臺(tái)主機(jī)在上線時(shí)首先就與服務(wù)器建立了連接,那么從主機(jī)A發(fā)往主機(jī)B發(fā)送消息,就可以通過(guò)這樣一條路徑,主機(jī)A --> 服務(wù)器 --> 主機(jī)B,通過(guò)這種方式,各個(gè)主機(jī)不需要在對(duì)端口進(jìn)行偵聽(tīng),而只需要服務(wù)器進(jìn)行偵聽(tīng)就可以了,大大地簡(jiǎn)化了開(kāi)發(fā)。
而對(duì)于一些較大的文件,比如說(shuō)圖片或者文件,如果想由主機(jī)A發(fā)往主機(jī)B,如果通過(guò)服務(wù)器進(jìn)行傳輸效率會(huì)比較低,此時(shí)可以臨時(shí)搭建一個(gè)主機(jī)A至主機(jī)B之間的連接,用于傳輸大文件。當(dāng)文件傳輸結(jié)束之后再關(guān)閉連接(桔紅色箭頭標(biāo)識(shí))。
除此以外,由于消息都經(jīng)過(guò)服務(wù)器,所以服務(wù)器還可以緩存主機(jī)間的對(duì)話,即是說(shuō)當(dāng)主機(jī)A發(fā)往主機(jī)B時(shí),如果主機(jī)B已經(jīng)離線,則服務(wù)器可以對(duì)消息進(jìn)行緩存,當(dāng)主機(jī)B下次連接到服務(wù)器時(shí),服務(wù)器自動(dòng)將緩存的消息發(fā)給主機(jī)B。
本系列文章最后采用的即是此種模式,不過(guò)沒(méi)有實(shí)現(xiàn)過(guò)多復(fù)雜的功能。接下來(lái)我們的理論知識(shí)告一段落,開(kāi)始下一階段――漫長(zhǎng)的編碼。
點(diǎn)擊加載更多評(píng)論>>