linux udp 單播 組播 廣播實(shí)現(xiàn)_第1頁(yè)
linux udp 單播 組播 廣播實(shí)現(xiàn)_第2頁(yè)
linux udp 單播 組播 廣播實(shí)現(xiàn)_第3頁(yè)
linux udp 單播 組播 廣播實(shí)現(xiàn)_第4頁(yè)
linux udp 單播 組播 廣播實(shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、linux udp單播組播廣播實(shí)現(xiàn)1、組播和廣播需要在局域網(wǎng)內(nèi)才能實(shí)現(xiàn),另外得查看linux系統(tǒng)是否支持多播和廣播:ifconfigUP BROADCAST MULTICAST MTU:1500 躍點(diǎn)數(shù):1說明該網(wǎng)卡支持2、發(fā)送多播包的主機(jī)需要設(shè)置網(wǎng)關(guān),否則運(yùn)行sendto()會(huì)出現(xiàn)network is unreachable,網(wǎng) 卡可以隨便設(shè)置,但是一定要設(shè)。還要添加路由,即:route add -net netmask dev eth0route add default gw dev eth03、出現(xiàn):“setsockopt:No such device”。的提示,說明多播IP設(shè)置出現(xiàn)問題

2、,系統(tǒng)所需要的 uint32_t格式的網(wǎng)絡(luò)地址的開頭不是1110,檢驗(yàn)通不過。解決辦法:在把地址字符串*.*.*.* 轉(zhuǎn)化為 uint32_t 時(shí)采用 htonl(inet_network(“*.*.*.*)或者 inet_aton 函數(shù),inet_aton(GRUPO, &srv.sin_addr)另外有文章: HYPERLINK /unixcd1Zarticle_5577.html /unixcd1Zarticle_5577.html11.3 多 播單播用于兩個(gè)主機(jī)之間的端對(duì)端通信,廣播用于一個(gè)主機(jī)對(duì)整個(gè)局域網(wǎng)上所有主機(jī)上的數(shù)據(jù) 通信。單播和廣播是兩個(gè)極端,要么對(duì)一個(gè)主機(jī)進(jìn)行通信,要么對(duì)整

3、個(gè)局域網(wǎng)上的主機(jī)進(jìn)行 通信。實(shí)際情況下,經(jīng)常需要對(duì)一組特定的主機(jī)進(jìn)行通信,而不是整個(gè)局域網(wǎng)上的所有主機(jī), 這就是多播的用途。11.3.1多播的概念多播,也稱為“組播”,將網(wǎng)絡(luò)中同一業(yè)務(wù)類型主機(jī)進(jìn)行了邏輯上的分組,進(jìn)行數(shù)據(jù)收發(fā)的 時(shí)候其數(shù)據(jù)僅僅在同一分組中進(jìn)行,其他的主機(jī)沒有加入此分組不能收發(fā)對(duì)應(yīng)的數(shù)據(jù)。在廣域網(wǎng)上廣播的時(shí)候,其中的交換機(jī)和路由器只向需要獲取數(shù)據(jù)的主機(jī)復(fù)制并轉(zhuǎn)發(fā)數(shù)據(jù)。 主機(jī)可以向路由器請(qǐng)求加入或退出某個(gè)組,網(wǎng)絡(luò)中的路由器和交換機(jī)有選擇地復(fù)制并傳輸數(shù) 據(jù),將數(shù)據(jù)僅僅傳輸給組內(nèi)的主機(jī)。多播的這種功能,可以一次將數(shù)據(jù)發(fā)送到多個(gè)主機(jī),又 能保證不影響其他不需要(未加入組)的主機(jī)的其他通信

4、。相對(duì)于傳統(tǒng)的一對(duì)一的單播,多播具有如下的優(yōu)點(diǎn):q具有同種業(yè)務(wù)的主機(jī)加入同一數(shù)據(jù)流,共享同一通道,節(jié)省了帶寬和服務(wù)器的優(yōu)點(diǎn),具有 廣播的優(yōu)點(diǎn)而又沒有廣播所需要的帶寬。q服務(wù)器的總帶寬不受客戶端帶寬的限制。由于組播協(xié)議由接收者的需求來確定是否進(jìn)行數(shù) 據(jù)流的轉(zhuǎn)發(fā),所以服務(wù)器端的帶寬是常量,與客戶端的數(shù)量無關(guān)。q與單播一樣,多播是允許在廣域網(wǎng)即Internet上進(jìn)行傳輸?shù)?,而廣播僅僅在同一局域網(wǎng)上 才能進(jìn)行。組播的缺點(diǎn):q多播與單播相比沒有糾錯(cuò)機(jī)制,當(dāng)發(fā)生錯(cuò)誤的時(shí)候難以彌補(bǔ),但是可以在應(yīng)用層來實(shí)現(xiàn)此 種功能。q多播的網(wǎng)絡(luò)支持存在缺陷,需要路由器及網(wǎng)絡(luò)協(xié)議棧的支持。多播的應(yīng)用主要有網(wǎng)上視頻、網(wǎng)上會(huì)議等

5、。11.3.2 廣域網(wǎng)的多播多播的地址是特定的,D類地址用于多播。D類IP地址就是多播IP地址,即至 55之間的IP地址,并被劃分為局部連接多播地址、預(yù)留多播地址和管理權(quán)限 多播地址3類:q局部多播地址:在55之間,這是為路由協(xié)議和其他用途保留的地址, 路由器并不轉(zhuǎn)發(fā)屬于此范圍的IP包。q預(yù)留多播地址:在55之間,可用于全球范圍(如Internet)或網(wǎng) 絡(luò)協(xié)議。q管理權(quán)限多播地址:在55之間,可供組織內(nèi)部使用,類似于私有IP地址,不能用于Internet,可限制多播范圍。11.3.3多播的編程多播的程序設(shè)計(jì)使用setsockopt()函數(shù)和getsockopt()函數(shù)來實(shí)現(xiàn),組播的選項(xiàng)是IP

6、層的,其 選項(xiàng)值和含義參見11.5所示。表11.5多播相關(guān)的選項(xiàng)getsockopt()/setsockopt()的 選項(xiàng)含義IP_MULTICAST_TTL設(shè)置多播組數(shù)據(jù)的TTL值IP_ADD_MEMBERSHIP在指定接口上加入組播組IP_DROP_MEMBERSHIP退出組播組IP_MULTICAST_IF獲取默認(rèn)接口或設(shè)置接口IP_MULTICAST_LOOP禁止組播數(shù)據(jù)回送選項(xiàng) IP_MULTICASE_TTL選項(xiàng)IP_MULTICAST_TTL允許設(shè)置超時(shí)TTL,范圍為0255之間的任何值,例如: unsigned char ttl=255;setsockopt(s,IPPROTO

7、_IPIP_MULTICAST_TTL,&ttl,sizeof(ttl);選項(xiàng) IP_MULTICAST_IF選項(xiàng)IP_MULTICAST_IF用于設(shè)置組播的默認(rèn)默認(rèn)網(wǎng)絡(luò)接口,會(huì)從給定的網(wǎng)絡(luò)接口發(fā)送,另一 個(gè)網(wǎng)絡(luò)接口會(huì)忽略此數(shù)據(jù)。例如:struct in_addr addr;setsockopt(s,IPPROTO_IPIP_MULTICAST_IF,&addr,sizeof(addr);參數(shù)addr是希望多播輸出接口的IP地址,使用INADDR_ANY地址回送到默認(rèn)接口。默認(rèn)情況下,當(dāng)本機(jī)發(fā)送組播數(shù)據(jù)到某個(gè)網(wǎng)絡(luò)接口時(shí),在IP層,數(shù)據(jù)會(huì)回送到本地的回環(huán) 接口,選項(xiàng)IP_MULTICAST_LO

8、OP用于控制數(shù)據(jù)是否回送到本地的回環(huán)接口。例如: unsigned char loop;setsockopt(s,IPPROTO_IPIP_MULTICAST_LOOP&loop,sizeof(loop);參數(shù)loop設(shè)置為0禁止回送,設(shè)置為1允許回送。選項(xiàng) IP_ADD_MEMBERSHIP 和 IP_DROP_MEMBERSHIP加入或者退出一個(gè)組播組,通過選項(xiàng)IP_ADD_MEMBERSHIP和IP_DROP_MEMBER- SHIP,對(duì)一 個(gè)結(jié)構(gòu)struct ip_mreq類型的變量進(jìn)行控制,struct ip_mreq原型如下: struct ip_mreqstruct in_add

9、r imn_multiaddr; /*加入或者退出的廣播組IP地址*/struct in_addr imr_interface; /*加入或者退出的網(wǎng)絡(luò)接口 IP地址*/;選項(xiàng)IP_ADD_MEMBERSHIP用于加入某個(gè)廣播組,之后就可以向這個(gè)廣播組發(fā)送數(shù)據(jù)或者從 廣播組接收數(shù)據(jù)。此選項(xiàng)的值為mreq結(jié)構(gòu),成員imn_multiaddr是需要加入的廣播組IP地 址,成員imr_interface是本機(jī)需要加入廣播組的網(wǎng)絡(luò)接口 IP地址。例如: struct ip_mreq mreq;setsockopt(s,IPPROTO_IPIP_ADD_MEMBERSHIF,&mreq,sizeof(m

10、req);使用IP_ADD_MEMBERSHIP選項(xiàng)每次只能加入一個(gè)網(wǎng)絡(luò)接口的IP地址到多播組,但并不是一 個(gè)多播組僅允許一個(gè)主機(jī)IP地址加入,可以多次調(diào)用IP_ADD_MEMBERSHIP選項(xiàng)來實(shí)現(xiàn)多個(gè) IP地址加入同一個(gè)廣播組,或者同一個(gè)IP地址加入多個(gè)廣播組。當(dāng)imr_ interface為 INADDR_ANY時(shí),選擇的是默認(rèn)組播接口。選項(xiàng) IP_DROP_MEMBERSHIP選項(xiàng)IP_DROP_MEMBERSHIP用于從一個(gè)廣播組中退出。例如:struct ip_mreq mreq;setsockopt(s,IPPROTP_IPIP_DROP_MEMBERSHIF,&mreq,siz

11、eof(sreq);其中mreq包含了在IP_ADD_MEMBERSHIP中相同的值。多播程序設(shè)計(jì)的框架要進(jìn)行多播的編程,需要遵從一定的編程框架,其基本順序如圖11.6所示。多播程序框架主要包含套接字初始化、設(shè)置多播超時(shí)時(shí)間、加入多播組、發(fā)送數(shù)據(jù)、接收數(shù) 據(jù)以及從多播組中離開幾個(gè)方面。其步驟如下:建立一個(gè) socketo然后設(shè)置多播的參數(shù),例如超時(shí)時(shí)間TTL、本地回環(huán)許可LOOP等。加入多播組。發(fā)送和接收數(shù)據(jù)。從多播組離開。11.3.4內(nèi)核中的多播Linux內(nèi)核中的多播是利用結(jié)構(gòu)struct ip_mc_socklist來將多播的各個(gè)方面連接起來的,其示 意圖如圖11.7所示。圖11.7多播的

12、內(nèi)核結(jié)構(gòu)struct inet_sock u8 mc_ttl; /*多播 TTL*/ _u8 .mc_loop:1; /*多播回環(huán)設(shè)置*/int mc_index; /*多播設(shè)備序號(hào)*/_be32 mc_addr; /* 多播地址*/struct ip_mc_socklist *mc_list; /* 多播群數(shù)組 */.;q結(jié)構(gòu)成員mc_ttl用于控制多播的TTL;q結(jié)構(gòu)成員mc_loop表示是否回環(huán)有效,用于控制多播數(shù)據(jù)的本地發(fā)送;q結(jié)構(gòu)成員mc_index用于表示網(wǎng)絡(luò)設(shè)備的序號(hào);q結(jié)構(gòu)成員mc_addr用于保存多播的地址;q結(jié)構(gòu)成員mc_list用于保存多播的群組。1.結(jié)構(gòu) ip_mc_s

13、ocklist結(jié)構(gòu)成員mc_list的原型為struct ip_mc_socklist,定義如下:struct ip_mc_sockliststruct ip_mc_socklist *next;struct ip_mreqn multi;unsigned int sfmode; /*MCAST_INCLUDE,EXCLUDE*/struct ip_sf_socklist *sflist;q成員參數(shù)next指向鏈表的下一個(gè)節(jié)點(diǎn)。q成員參數(shù)multi表示組信息,即在哪一個(gè)本地接口上,加入到哪一個(gè)多播組。q成員參數(shù)sfmode是過濾模式,取值為MCAST_INCLUDE或MCAST_EXCLUDE

14、,分別表示只 接收sflist所列出的那些源的多播數(shù)據(jù)報(bào),和不接收sflist所列出的那些源的多播數(shù)據(jù)報(bào)。q成員參數(shù)sflist是源列表。結(jié)構(gòu) ip_mreqnmulti成員的原型為結(jié)構(gòu)struct ip_mreqn,定義如下:struct ip_mreqnstruct in_addr imr_multiaddr; /*多播組的 IP 地址*/struct in_addr imr_address; /*本地址網(wǎng)絡(luò)接口的 IP 地址*/int imr_ifindex; /* 網(wǎng)絡(luò)接口序號(hào) */;該結(jié)構(gòu)體的兩個(gè)成員分別用于指定所加入的多播組的組IP地址,和所要加入組的那個(gè)本地 接口的IP地址。該命

15、令字沒有源過濾的功能,它相當(dāng)于實(shí)現(xiàn)IGMPV1的多播加入服務(wù)接口。結(jié)構(gòu) ip_sf_socklist成員sflist的原型為結(jié)構(gòu)struct ip_sf_socklist,定義如下:struct ip_sf_socklistunsigned int sl_max; /*當(dāng)前sl_addr數(shù)組的最大可容納量*/unsigned int sl_count; /*源地址列表中源地址的數(shù)量*/_u32 sl_addr0; /* 源地址列表 */;q成員參數(shù)sl_addr表示是源地址列表;q成員參數(shù)sl_count表示是源地址列表中源地址的數(shù)量;q成員參數(shù)sl_max表示是當(dāng)前sl_addr數(shù)組的最大可

16、容納量(不確定)。選項(xiàng) IP_ADD_MEMBERSHIP選項(xiàng)IP_ADD_MEMBERSHIP用于把一個(gè)本地的IP地址加入到一個(gè)多播組,在內(nèi)核中其處理過 程如圖11.8所示,在應(yīng)用層調(diào)用函數(shù)setsockopt()函數(shù)的選項(xiàng)IP_ADD_MEMBE- RSHIP后,內(nèi) 核的處理過程如下,主要調(diào)用了函數(shù)ip_mc_join_group()。圖11.8選項(xiàng)IP_ADD_MEMBERSHIP的內(nèi)核處理過程將用戶數(shù)據(jù)復(fù)制如內(nèi)核。判斷廣播IP地址是否合法。查找IP地址對(duì)應(yīng)的網(wǎng)絡(luò)接口。查找多播列表中是否已經(jīng)存在多播地址。將此多播地址加入列表。返回處理值。選項(xiàng) IP_DROP_MEMBERSHIP選項(xiàng)IP

17、_DROP_MEMBERSHIP用于把一個(gè)本地的IP地址從一個(gè)多播組中取出,在內(nèi)核中其處 理過程如圖11.9所示,在應(yīng)用層調(diào)用setsockopt()l數(shù)的選項(xiàng)IP_DROP_ MEMBERSHIP后,內(nèi) 核的處理過程如下,主要調(diào)用了函數(shù)ip_mc_leave_group()。IRift名插捫WlSWkqMfS.IPPROTQ IPJP DROP浪SHIP.我叩咽目嘩河口窿q);郵屋根摳等捕uwl Rm咧何勺找網(wǎng)站的Iip me leave imL in devf;ipgmuplin. dct8 gmup):返同所imr muHigtddr addr f conHnue;If (iflndex

18、j ir(iimp:-niulii.imrjfindex! ilindlt coniiiuje:! /I地if。加卜巾冊(cè) Mid梃崩& ftddfInir- imifmddr muliiJinr ddress.s addr)ccminiK; 一將膈戶數(shù)據(jù)甄制到冉棱 .f捅紐copy Irani U!icflimn:q,nptval icotlsliwi ip_ffirci|R / ip me leave greupHsk, -itmirq J;圖11.9選項(xiàng)IP_DROP_MEMBERSHIP的內(nèi)核處理過程(1)將用戶數(shù)據(jù)復(fù)制入內(nèi)核。(2)查找IP地址對(duì)應(yīng)的網(wǎng)絡(luò)接口。(3)查找多播列表中是否已

19、經(jīng)存在多播地址。(4)將此多播地址從源地址中取出。(5)將此地址結(jié)構(gòu)從多播列表中取出。(6)返回處理值。11.3.5 一個(gè)多播例子的服務(wù)器端下面是一個(gè)多播服務(wù)器的例子。多播服務(wù)器的程序設(shè)計(jì)很簡(jiǎn)單,建立一個(gè)數(shù)據(jù)包套接字,選 定多播的IP地址和端口,直接向此多播地址發(fā)送數(shù)據(jù)就可以了。多播服務(wù)器的程序設(shè)計(jì), 不需要服務(wù)器加入多播組,可以直接向某個(gè)多播組發(fā)送數(shù)據(jù)。下面的例子持續(xù)向多播IP地址8的8888端口發(fā)送數(shù)據(jù)BROADCAST TEST DATA,每發(fā)送一次間隔5s。/*broadcast_server.c -多播服務(wù)程序*/#define MCAST_PORT 8888;#define MCA

20、ST_ADDR 8/ /* 一個(gè)局部連接多播地址,路由器不進(jìn)行轉(zhuǎn)發(fā)*/#define MCAST_DATA BROADCAST TEST DATA /多播發(fā)送的數(shù)據(jù) *#define MCAST_INTERVAL 5 /* 發(fā)送間隔時(shí)間 */int main(int argc, char*argv)int s;struct sockaddr_in mcast_addr;s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字 */if (s = -1)perror(socket();return -1;memset(&mcast_addr, 0, sizeof(m

21、cast_addr);/*初始化 IP 多播地址為 0*/mcast_addr.sin_family = AF_INET; /設(shè)置協(xié)議族類行為 AF*/mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/設(shè)置多播 IP 地址*/ mcast_addr.sin_port = htons(MCAST_PORT); /設(shè)置多播端口 */*向多播地址發(fā)送數(shù)據(jù)*/while(1) int n = sendto(s, /*套接字描述符*/MCAST_DATA, /*數(shù)據(jù) */sizeof(MCAST_DATA), /長(zhǎng)度 */0,(struct sock

22、addr*)&mcast_addr,sizeof(mcast_addr);if( n 0)perror(sendto();return -2;sleep(MCAST_INTERVAL); /*等待一段時(shí)間 */return 0;11.3.6 一個(gè)多播例子的客戶端多播組的IP地址為8,端口為8888,當(dāng)客戶端接收到多播的數(shù)據(jù)后將打印出來。 客戶端只有在加入多播組后才能接受多播組的數(shù)據(jù),因此多播客戶端在接收多播組的數(shù)據(jù)之 前需要先加入多播組,當(dāng)接收完畢后要退出多播組。/*broadcast_client.c -多播的客戶端*/#define MCAST_PORT 8888;#define MCAS

23、T_ADDR 8 /*一個(gè)局部連接多播地址,路由器不進(jìn)行轉(zhuǎn)發(fā)*/#define MCAST_INTERVAL 5 /* 發(fā)送間隔時(shí)間 */#define BUFF_SIZE 256 /* 接收緩沖區(qū)大小*/int main(int argc, char*argv)int s; /*套接字文件描述符*/struct sockaddr_in local_addr; /*本地地址 */int err = -1;s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字 */if (s = -1)perror(socket();return -1;/*初始化地址*/mems

24、et(&local_addr, 0, sizeof(local_addr);local_addr.sin_family = AF_INET;local_addr.sin_addr.s_addr = htonl(INADDR_ANY);local_addr.sin_port = htons(MCAST_PORT);/*綁定 socket*/err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr);if(err 0)perror(bind();return -2;/*設(shè)置回環(huán)許可*/int loop = 1;err = setso

25、ckopt(s,IPPROTO_Ip IP_MULTICAST_LOOp&loop, sizeof(loop);if(err 0)perror(setsockopt():IP_MULTICAST_LOOP);return -3;struct ip_mreq mreq; /*加入廣播組 */mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*廣 播地址 */ mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* 網(wǎng)絡(luò)接口為默認(rèn)*/*將本機(jī)加入廣播組*/err = setsockopt(s, IPP

26、ROTO_IP IP_ADD_MEMBERSHIR&mreq, sizeof (mreq);if (err 0)perror(setsockopt():IP_ADD_MEMBERSHIP);return -4;int times = 0;int addr_len = 0;char buffBUFF_SIZE;int n = 0;/*循環(huán)接收廣播組的消息,5次后退出*/for(times = 0;timesi - -n闕由UJ*址四配櫓收程序圖11.4廣播的以太網(wǎng)示意圖11.2.3廣播的示例本節(jié)中是一個(gè)服務(wù)器地址發(fā)現(xiàn)的代碼,假設(shè)服務(wù)器為A,客戶端為B??蛻舳嗽谀硞€(gè)局域網(wǎng)啟動(dòng) 的時(shí)候,不知道本局域

27、網(wǎng)內(nèi)是否有適合的服務(wù)器存在,它會(huì)使用廣播在本局域網(wǎng)內(nèi)發(fā)送特定協(xié) 議的請(qǐng)求,如果有服務(wù)器響應(yīng)了這種請(qǐng)求,則使用響應(yīng)請(qǐng)求的IP地址進(jìn)行連接,這是一種服務(wù) 器/客戶端自動(dòng)發(fā)現(xiàn)的常用方法。1 .廣播例子簡(jiǎn)介如圖11.5所示為使用廣播的方法發(fā)現(xiàn)局域網(wǎng)上服務(wù)器的IP地址。服務(wù)器在局域網(wǎng)上偵聽,當(dāng)有 數(shù)據(jù)到來的時(shí)候,判斷數(shù)據(jù)是否有關(guān)鍵字IP_FOUND,當(dāng)存在此關(guān)鍵字的時(shí)候,發(fā)送 IP_FOUND_ACK到客戶端??蛻舳伺袛嗍欠裼蟹?wù)器的響應(yīng)IP_FOUND請(qǐng)求,并判斷響應(yīng)字符串 是否包含IP_FOUND_ACK來確定局域網(wǎng)上是否存在服務(wù)器,如果有服務(wù)器的響應(yīng),則根據(jù) recvfrom()函數(shù)的from變量

28、可以獲得服務(wù)器的IP地址。圖11.5利用廣播進(jìn)行服務(wù)器IP地址的發(fā)現(xiàn)廣播的服務(wù)器端代碼服務(wù)器的代碼如下,服務(wù)器等待客戶端向某個(gè)端口發(fā)送數(shù)據(jù),如果數(shù)據(jù)的格式正確,則服務(wù)器 會(huì)向客戶端發(fā)送響應(yīng)數(shù)據(jù)。0102 #define IP_FOUND IP_FOUND /*IP 發(fā)現(xiàn)命令 */03 #define IP_FOUND_ACK IP_FOUND_ACK /*IP 發(fā)現(xiàn)應(yīng)答命令 */04 void HandleIPFound(void*arg)05 06 #define BUFFER_LEN 3207 int ret = -1;08 SOCKET sock = -1;09 struct socka

29、ddr_in local_addr; /*本地地址 */struct sockaddr_in from_addr; /*客戶端地址*/int from_len;int count = -1;fd_set readfd;char buffBUFFER_LEN;struct timeval timeout;timeout.tv_sec = 2; /*超時(shí)時(shí)間 2s*/timeout.tv_usec = 0;1819 DBGPRINT(=HandleIPFoundn);20sock = socket(AF_INET, SOCK_DGRAM, 0); /*建立數(shù)據(jù)報(bào)套接字 */if( sock 0 )

30、DBGPRINT(HandleIPFound: socket init errorn);return;27/*數(shù)據(jù)清零*/memset(void*)&local_addr, 0, sizeof(struct sockaddr_in);/*清空內(nèi)存內(nèi)容*/local_addr.sin_family = AF_INET; /*協(xié)議族 */local_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*本地地址 */local_addr.sin_port = htons(MCAST_PORT); /*貞聽端口*/*綁定*/ret = bind(sock, (stru

31、ct sockaddr*)&local_addr, sizeof(local_ addr);if(ret != 0) TOC o 1-5 h z DBGPRINT(HandleIPFound:bind errorn);return;40/*主處理過程*/while(1)/*文件描述符集合清零*/FD_ZERO(&readfd);/*將套接字文件描述符加入讀集合*/FD_SET(sock, &readfd);/*select偵聽是否有數(shù)據(jù)到來*/ret = selectsocket(sock+1, &readfd, NULL, NULL, &timeout);switch(ret)case -1

32、:/*發(fā)生錯(cuò)誤*/break;case 0:/*超時(shí)*/超時(shí)所要執(zhí)行的代碼58break;default:/*有數(shù)據(jù)到來*/if( FD_ISSET( sock, &readfd )/*接收數(shù)據(jù)*/count = recvfrom( sock, buff, BUFFER_LEN, 0, (struct sockaddr*) &from_addr, &from_len );DBGPRINT( Recv msg is %sn, buff );if( strstr( buff, IP_FOUND )/*判斷是否吻合*/*將應(yīng)答數(shù)據(jù)復(fù)制進(jìn)去*/memcpy(buff, IP_FOUND_ACK,str

33、len(IP_FOUND_ACK)+1);/*發(fā)送給客戶端*/count = sendto( sock, buff, strlen( buff ),0, ( struct sockaddr*) &from_addr, from_len ); TOC o 1-5 h z PRINT(=HandleIPFoundn);78return;服務(wù)器端分為如下步驟:q第16行和第17行定義了服務(wù)器等待的超時(shí)時(shí)間,為2s。q第29行將地址結(jié)構(gòu)清零。q第30行定義地址協(xié)議族為AF_INET。q第31行設(shè)置IP地址為任意本地地址。q第32行設(shè)置偵聽的端口。q第34行將本地的地址綁定到一個(gè)套接字文件描述符上。q第

34、42行開始為主處理過程,使用select函數(shù),按照2s的超時(shí)時(shí)間偵聽是否有數(shù)據(jù)到來。q第45行文件描述符集合清零。q第47行將套接字文件描述符加入讀集合。q第49行select偵聽是否有數(shù)據(jù)到來。q第50行查看select的返回值。q第52行select發(fā)生錯(cuò)誤。q第55行select超時(shí)。q第60行有可讀的數(shù)據(jù)到來。q第65行接收數(shù)據(jù)。q第67行查看接收到的數(shù)據(jù)是否匹配。q第70行復(fù)制響應(yīng)數(shù)據(jù)。q第72行發(fā)送響應(yīng)數(shù)據(jù)到客戶端。廣播的客戶端代碼廣播的客戶端函數(shù)代碼如下,客戶端向服務(wù)器端發(fā)送命令I(lǐng)P_FOUND,并等待服務(wù)器端的回復(fù), 如果有服務(wù)器回復(fù),則向服務(wù)器發(fā)送IP_FOUND_ACK,否

35、則發(fā)送10遍后退出。01 #define IP_FOUND IP_FOUND /*IP 發(fā)現(xiàn)命令 */02 #define IP_FOUND_ACK IP_FOUND_ACK /*IP 發(fā)現(xiàn)應(yīng)答命令 */03 #define IFNAME eth004 void IPFound(void*arg)05 06 #define BUFFER_LEN 3207 int ret = -1;08 SOCKET sock = -1;09 int so_broadcast = 1;struct ifreq ifr;struct sockaddr_in broadcast_addr; /*本地地址*/stru

36、ct sockaddr_in from_addr; /*服務(wù)器端地址 */int from_len;int count = -1;fd_set readfd;char buffBUFFER_LEN;struct timeval timeout;timeout.tv_sec = 2; /*超時(shí)時(shí)間 2s*/timeout.tv_usec = 0;2021sock = socket(AF_INET, SOCK_DGRAM, 0);/*建 立數(shù)據(jù)報(bào)套接字*/if( sock 0 )DBGPRINT(HandleIPFound: socket init errorn);return;/*將需要使用的網(wǎng)絡(luò)接口字符串名字復(fù)制到結(jié)構(gòu)中*/strcpy(ifr.ifr_name,IFNAME,strlen(IFNAME);/*發(fā)送命令,獲取網(wǎng)絡(luò)接口的廣播地址*/if(ioctl(sock,SIOCGIFBRDADDR,&ifr) = -1)perror(ioctl error),exit(1);/*將獲得的廣播地址復(fù)制給變量broadcast_addr*/memcpy(&broadcast_addr, &ifr.ifr_broadaddr, sizeof(struct sockaddr_in

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論