Unix網(wǎng)絡(luò)編程-UDP客戶端服務(wù)器示例(2)

一個(gè)簡單的UDP客戶端/服務(wù)器程序示例,這個(gè)簡單的例子執(zhí)行如下步驟的一個(gè)回射服務(wù)器:

1) 客戶端從標(biāo)準(zhǔn)輸入讀入一行文本,并寫給服務(wù)端

2) 服務(wù)端從網(wǎng)絡(luò)輸入讀入一行文本,并回射給客戶端

3) 客戶端從網(wǎng)絡(luò)輸入讀入這行回射的文件,并顯示在標(biāo)準(zhǔn)輸出上。

下圖描述了這個(gè)簡單的客戶/服務(wù)器:

UDP回射服務(wù)器程序和UDP回射客戶端程序見上篇,略

數(shù)據(jù)報(bào)的丟失

我們的UDP客戶/服務(wù)器例子是不可靠的。如果一個(gè)客戶數(shù)據(jù)報(bào)丟失(譬如說,被客戶主機(jī)與服務(wù)器主機(jī)之間的某個(gè)路由器丟棄),客戶端將永遠(yuǎn)阻塞于dg_cli函數(shù)中的recvfrom調(diào)用,等待一個(gè)永遠(yuǎn)不會(huì)到達(dá)的服務(wù)器應(yīng)答。類似的,如果客戶數(shù)據(jù)報(bào)到達(dá)服務(wù)器,但是服務(wù)器的應(yīng)答丟失了,客戶端也將永遠(yuǎn)阻塞于recvfrom調(diào)用。防止這樣永遠(yuǎn)阻塞的一般方法是給客戶的recvfrom調(diào)用設(shè)置一個(gè)超時(shí)。

僅僅給recvfrom調(diào)用設(shè)置超時(shí)并不是完整的解決辦法。舉例來說,如果確實(shí)超時(shí)了,我們將無從判定超時(shí)的原因是我們的數(shù)據(jù)報(bào)沒有到達(dá)服務(wù)器,還是服務(wù)器的應(yīng)答沒有回到客戶。如果客戶的請(qǐng)求是“從賬戶A往賬戶B轉(zhuǎn)一定數(shù)目的錢”而不是我們的簡單回射服務(wù)器例子,那么請(qǐng)求丟失和應(yīng)帶丟失是極不相同的。因此需要給UDP增加可靠性

驗(yàn)證接收的響應(yīng)

知道客戶臨時(shí)端口號(hào)的任何進(jìn)程都可以給客戶發(fā)送數(shù)據(jù)報(bào),而且這些數(shù)據(jù)報(bào)會(huì)與正常的服務(wù)器應(yīng)答混雜??梢詒ecvform調(diào)用以返回?cái)?shù)據(jù)報(bào)發(fā)送者的IP地址和端口號(hào),保留來自服務(wù)器的應(yīng)答,忽略任何其他的數(shù)據(jù)報(bào)。

如下所示:

如果服務(wù)器是運(yùn)行在一個(gè)只有單個(gè)IP地址的主機(jī)上,那么這個(gè)新版的客戶端能正常工作。然后如果客戶端是多宿的,客戶端就有可能失敗。因?yàn)閞ecvfrom返回的IP地址,可能不是我們發(fā)送指定的IP地址,服務(wù)器可能選擇從其他的IP作為外出接口。

一個(gè)解決辦法是:得到recvfrom返回的IP地址后,客戶端通過在DNS中查找服務(wù)器主機(jī)的名字來驗(yàn)證該主機(jī)的域名而不是IP地址。另一個(gè)解決辦法是:服務(wù)端為每個(gè)IP地址創(chuàng)建一個(gè)套接字,用bind捆綁各自的IP到各自的套接字。這樣,就會(huì)從對(duì)應(yīng)的IP地址上響應(yīng)客戶端。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容