有些时候今日事今日毕未必是好事,今天解决不了的bug留到明天或许就解决了
特点:
较TCP来讲UDP无需建立连接可以直接发送消息,UDP是对网络环境完全不弥补的协议,所以使用DUP就要允许有一定的丢包率,UDP广播是面向局域网内所有的设备的。
对比TCP连接时服务端的IP地址的重要性来讲,UDP广播中本机的IP显得并不重要了。
广播地址:
我们知道在IPV4地址中是采用点分十进制的方法来表示IP地址的,占用4个字节来存储IP地址,这样就决定了IPV4地址每段的最大值为1111 1111 折合十进制正好是255,在IP地址的设定中.1和255是不能被使用的.1表示网关,.255为广播地址。
在UDP广播中不同于TCP的我们需要对网络套接字设置其广播属性,默认的 网络套接字是不具有广播属性的,这里使用setsockopt函数,对于这函数manpage中无详细介绍具体使用可以参照UNIX网络编程一卷,我们使用sendto函数将数据报发送给目标地址为.255的IP地址,当交换机收到我们发送的数据报时会对其解包,交换机发现IP地址为255时会把数据报发送到局域网内每一个主机
发送端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
int main(){
char msg[128] = "I am broadCast message from server!";
struct sockaddr_in saddr, caddr;
socklen_t slen, clen;
int lfd, ret;
lfd = socket(AF_INET, SOCK_DGRAM, 0);
if(lfd < 0){
perror("socket create error");
exit(1);
}
int flag = 1;
setsockopt(lfd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &flag, sizeof(flag) );
caddr.sin_family = AF_INET;
caddr.sin_port = htons(4001);
caddr.sin_addr.s_addr = inet_addr("192.168.10.255");
clen = sizeof(caddr);
int n = sendto(lfd, msg, strlen(msg), 0, (struct sockaddr *)&caddr, clen);
if(n < 0){
perror("sendto Error:");
exit(1);
}
close(lfd);
return 0;
}
接收端
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<arpa/inet.h>
int main(){
int sockListen;
if((sockListen = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
printf("socket fail\n");
return -1;
}
int set = 1;
setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(int));
struct sockaddr_in recvAddr;
memset(&recvAddr, 0, sizeof(struct sockaddr_in));
recvAddr.sin_family = AF_INET;
recvAddr.sin_port = htons(4001);
recvAddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sockListen, (struct sockaddr *)&recvAddr, sizeof(struct sockaddr)) == -1){
printf("bind fail\n");
return -1;
}
int recvbytes;
char recvbuf[128];
int addrLen = sizeof(struct sockaddr_in);
if((recvbytes = recvfrom(sockListen, recvbuf, 128, 0,
(struct sockaddr *)&recvAddr, &addrLen)) != -1){
recvbuf[recvbytes] = '\0';
printf("receive a broadCast messgse:%s\n", recvbuf);
}else{
printf("recvfrom fail\n");
}
close(sockListen);
return 0;
}
注意在client端中的ip地址绑定不要绑定127.0.0.1,这是本地环回地址只可以用于一台机器的测试,UDP广播是对于整个局域网通信的,