日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux网络编程之广播详细代码及文档说明 -,Linux网络编程之广播

發布時間:2023/12/10 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux网络编程之广播详细代码及文档说明 -,Linux网络编程之广播 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.概念

前面介紹的TCP,UDP都是單播方式,即一對一.而廣播是一臺主機向局域網內的所有主機發送數據。這時,同一網段的所有主機都能接收到數據。發送廣播包的步驟大致如下:

(1)確定一個發送廣播的接口,如eth0

(2)確定廣播的地址,通過ioctl函數,請求碼設置為SIOCGIFBRDADDR得到廣播的地址

(3)使用這個廣播地址進行廣播

由于TCP協議是端到端的協議,在通信之前,必須建立連接,三次握手之后才能發送數據。而廣播是一對多的通信,所以TCP不支持廣播。在局域網內,廣播通常用來探測服務器。

2. 探測服務器實例

這個例子通過在局域網內發送廣播包,收到廣播包的服務器,應答主機。這樣,就能夠探測到局域網內的服務器。

主機:

/**

客戶端實現廣播

**/

#define IP_FOUND "IP_FOUND"

#define IP_FOUND_ACK "IP_FOUND_ACK"

#define IFNAME "eth0"

#define MCAST_PORT 9999

int main(int argc,char*argv[]){

int ret=-1;

int sock=-1;

int so_broadcast=1;

struct ifreq ifr;

struct sockaddr_in broadcast_addr;//廣播地址

struct sockaddr_in from_addr;//服務端地址

int from_len=sizeof(from_addr);

int count=-1;

fd_set readfd;//讀文件描述符集合

char buffer[1024];

struct timeval timeout;

timeout.tv_sec=2;//超時時間為2秒

timeout.tv_usec=0;

sock=socket(AF_INET,SOCK_DGRAM,0);//建立數據報套接字

if(sock<0){

printf("HandleIPFound:sock init error\n");

return;

}

//將使用的網絡接口名字復制到ifr.ifr_name中,由于不同的網卡接口的廣播地址是不一樣的,因此指定網卡接口

strncpy(ifr.ifr_name,IFNAME,strlen(IFNAME));

//發送命令,獲得網絡接口的廣播地址

if(ioctl(sock,SIOCGIFBRDADDR,&ifr)==-1){

perror("ioctl error");

return;

}

//將獲得的廣播地址復制到broadcast_addr

memcpy(&broadcast_addr,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in));

//設置廣播端口號

printf("broadcast IP is:%s\n",inet_ntoa(broadcast_addr.sin_addr));

broadcast_addr.sin_family=AF_INET;

broadcast_addr.sin_port=htons(MCAST_PORT);

//默認的套接字描述符sock是不支持廣播,必須設置套接字描述符以支持廣播

ret=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));

//發送多次廣播,看網絡上是否有服務器存在

int times=10;

int i=0;

for(i=0;i //廣播發送服務器地址請求

timeout.tv_sec=2;//超時時間為2秒

timeout.tv_usec=0;

ret=sendto(sock,IP_FOUND,strlen(IP_FOUND),0,(struct sockaddr*)&broadcast_addr,sizeof(broadcast_addr));

if(ret==-1){

continue;

}

//文件描述符清0

FD_ZERO(&readfd);

//將套接字文件描述符加入到文件描述符集合中

FD_SET(sock,&readfd);

//select偵聽是否有數據到來

ret=select(sock+1,&readfd,NULL,NULL,&timeout);

switch(ret){

case -1:

break;

case 0:

printf("timeout\n");

break;

default:

//接收到數據

if(FD_ISSET(sock,&readfd)){

count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//from_addr為服務器端地址

printf("recvmsg is %s\n",buffer);

if(strstr(buffer,IP_FOUND_ACK)){

printf("found server IP is:%s\n",inet_ntoa(from_addr.sin_addr));

//服務器端的發送端口號

printf("Server Port:%d\n",htons(from_addr.sin_port));

}

return;

}

break;

}

}

return;

}

服務器:

/**

廣播服務器端代碼

**/

#define IP_FOUND "IP_FOUND"

#define IP_FOUND_ACK "IP_FOUND_ACK"

#define PORT 9999

int main(int argc,char*argv[]){

int ret=-1;

int sock;

struct sockaddr_in server_addr;//服務器端地址

struct sockaddr_in from_addr;//客戶端地址

int from_len=sizeof(struct sockaddr_in);

int count=-1;

fd_set readfd;//讀文件描述符集合

char buffer[1024];

struct timeval timeout;

timeout.tv_sec=2;

timeout.tv_usec=0;

sock=socket(AF_INET,SOCK_DGRAM,0);//建立數據報套接字

if(sock<0){

perror("sock error");

return;

}

memset((void*)&server_addr,0,sizeof(struct sockaddr_in));

server_addr.sin_family=AF_INET;

server_addr.sin_addr.s_addr=htons(INADDR_ANY);

server_addr.sin_port=htons(PORT);

//將地址結構綁定到套接字上./

ret=bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr));

if(ret<0){

perror("bind error");

return;

}

while(1){

timeout.tv_sec=2;

timeout.tv_usec=0;

//文件描述符集合清0

FD_ZERO(&readfd);

//將套接字描述符加入到文件描述符集合

FD_SET(sock,&readfd);

//select偵聽是否有數據到來

ret=select(sock+1,&readfd,NULL,NULL,&timeout);//偵聽是否可讀

printf("ret=%d\n",ret);

switch(ret){

case -1://發生錯誤

break;

case 0://超時

printf("timeout\n");

break;

default:

if(FD_ISSET(sock,&readfd)){

count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//接收客戶端發送的數據

//from_addr保存客戶端的地址結構

if(strstr(buffer,IP_FOUND)){

//響應客戶端請求

//打印客戶端的IP地址

printf("Client IP is%s\n",inet_ntoa(from_addr.sin_addr));

//打印客戶端的端口號

printf("Client Send Port:%d\n",ntohs(from_addr.sin_port));

memcpy(buffer,IP_FOUND_ACK,strlen(IP_FOUND_ACK)+1);

count=sendto(sock,buffer,strlen(buffer),0,(struct sockaddr*)&from_addr,from_len);//將數據發送給客戶端

}

return;

}

break;

}

}

return;

}

說明: 由于默認的套接字是不支持廣播的,所以必須設置套接字選項(setsockopt)來支持廣播。接口的廣播地址通過ioctl函數得到。廣播是基于UDP協議的。MAC地址是FF:FF:FF:FF:FF:FF.

總結

以上是生活随笔為你收集整理的linux网络编程之广播详细代码及文档说明 -,Linux网络编程之广播的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。