一種通過(guò)Udp進(jìn)行無(wú)確認(rèn)Ip的雙向的通信
前言
udp是一種不可靠的通信,但是有些時(shí)候還是會(huì)有使用。今天分享一個(gè)示例:主體邏輯,一個(gè)端口廣播地址,接收到ip地址數(shù)據(jù)后,其他端口基于這個(gè)ip進(jìn)行bind綁定,最后通信,這樣可以保證我們后續(xù)繼續(xù)增加端口交互時(shí)候不需要關(guān)注ip地址綁定的問(wèn)題。
主要原理介紹
- 低通信頻率端口進(jìn)行服務(wù)端IP信息udp廣播,接收端是不固定IP監(jiān)聽(tīng),監(jiān)聽(tīng)主機(jī)任意IP地址的特定端口
- 接收到廣播通道的ip地址后,與特定IP、port建立tcp或者udp雙向高頻率通信。
下圖是基于 UDP 的 Socket 函數(shù)調(diào)用過(guò)程:
只有接收的時(shí)候需要bind ip和端口
socket 監(jiān)聽(tīng)所有ip 特定端口代碼:
socket綁定的ip為INADDR_ANY 的說(shuō)明:
socket INADDR_ANY 監(jiān)聽(tīng)0.0.0.0地址 socket只綁定端口讓路由表決定傳到哪個(gè)ip
其中INADDR_ANY就是指定地址為0.0.0.0的地址,這個(gè)地址事實(shí)上表示不確定地址,或“所有地址”、“任意地址”。 如果指定ip地址為通配地址(INADDR_ANY),那么內(nèi)核將等到套接字已連接(TCP)或已在套接字上發(fā)出數(shù)據(jù)報(bào)時(shí)才選擇一個(gè)本地IP地址。 一般情況下,如果你要建立網(wǎng)絡(luò)服務(wù)器,則你要通知服務(wù)器操作系統(tǒng):請(qǐng)?jiān)谀车刂?xxx.xxx.xxx.xxx上的某端口 yyyy上進(jìn)行偵聽(tīng),并且把偵聽(tīng)到的數(shù)據(jù)包發(fā)送給我。這個(gè)過(guò)程,你是通過(guò)bind()系統(tǒng)調(diào)用完成的?!簿褪钦f(shuō),你的程序要綁定服務(wù)器的某地址,或者說(shuō):把服務(wù)器的某地址上的某端口占為已用。服務(wù)器操作系統(tǒng)可以給你這個(gè)指定的地址,也可以不給你。
如果你的服務(wù)器有多個(gè)網(wǎng)卡,而你的服務(wù)(不管是在udp端口上偵聽(tīng),還是在tcp端口上偵聽(tīng)),出于某種原因:可能是你的服務(wù)器操作系統(tǒng)可能隨時(shí)增減IP地址,也有可能是為了省去確定服務(wù)器上有什么網(wǎng)絡(luò)端口(網(wǎng)卡)的麻煩 —— 可以要在調(diào)用bind()的時(shí)候,告訴操作系統(tǒng):“我需要在 yyyy 端口上偵聽(tīng),所以發(fā)送到服務(wù)器的這個(gè)端口,不管是哪個(gè)網(wǎng)卡/哪個(gè)IP地址接收到的數(shù)據(jù),都是我處理的?!边@時(shí)候,服務(wù)器則在0.0.0.0這個(gè)地址上進(jìn)行偵聽(tīng)。無(wú)論連接哪個(gè)ip都可以連上的,只要是往這個(gè)端口發(fā)送的所有ip都能連上。
示例代碼:
data_send.c 在端口9001進(jìn)行ip地址的udp廣播以及讀取終端數(shù)據(jù)廣播到7000端口
data_process.c 進(jìn)行端口9001的ip數(shù)據(jù)的捕獲,當(dāng)接收到ip數(shù)據(jù)后,綁定廣播的ip地址進(jìn)行數(shù)據(jù)的收發(fā),這里用的是udp接收大家也可以試試tcp交互。
一個(gè)終端捕獲數(shù)據(jù),sudo tcpdump -i lo portrange 5000-8000 -vv -XX -nn,另外兩個(gè)終端進(jìn)行數(shù)據(jù)交互
結(jié)語(yǔ)
這就是我自己的一些udp設(shè)計(jì)思路的分享。如果大家有更好的想法和需求,也歡迎大家加我好友交流分享哈。
作者:良知猶存,白天努力工作,晚上原創(chuàng)公號(hào)號(hào)主。公眾號(hào)內(nèi)容除了技術(shù)還有些人生感悟,一個(gè)認(rèn)真輸出內(nèi)容的職場(chǎng)老司機(jī),也是一個(gè)技術(shù)之外豐富生活的人,攝影、音樂(lè) and 籃球。