官方网站建设推广,宁波快速制作网站,省建设厅网站合同备案用户名,小红书推广方式如何引流目录
1--多播
2--多播代码实例
3--广播
4--广播代码实例 1--多播 多播方式的数据传输是基于 UDP 完成的#xff0c;多播数据包的格式与 UDP 数据包相同#xff1b; 多播与 UDP 的区别#xff1a;UDP 数据传输以单一目标进行#xff0c;多播数据同时传递到加入#xff…目录
1--多播
2--多播代码实例
3--广播
4--广播代码实例 1--多播 多播方式的数据传输是基于 UDP 完成的多播数据包的格式与 UDP 数据包相同 多播与 UDP 的区别UDP 数据传输以单一目标进行多播数据同时传递到加入注册特定组的大量主机 多播的数据传输特点 ① 多播服务器端针对特定多播组只发送一次数据 ② 即使只发送 1 次数据该组内的所有客户端都会接收数据 ③ 多播组数可在 IP 地址范围内任意增加 ④ 加入特定组即可接收发往该多播组的数据 多播组使用的是 D 类IP地址224.0.0.0~239.255.255.255 为了传递多播数据包必须设置 TTLTime to LiveTTL 用整数表示每经过 1 个路由器 TTL 就会减 1当 TTL 变为 0 时数据包无法再被传递 // 与 TTL 相关的协议层是 IPPROTO_IP选项名为IP_MULTICAST_TTL
// 以下伪代码将 TTL 设置为 64
int send_sock;
int time_live 64;
send_sock socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST, (void*) time_live, sizeof(time_live));// 与加入多播组相关的协议层是 IPPROTO_IP选项名为IP_ADD_MEMBERSHIP
// 以下伪代码实现加入多播组
int recv_sock;
struct ip_mreq join_adr;
...
recv_sock socket(PFINET, SOCK_DGRAM, 0);
...
join_adr.imr_multiaddr.s_addr 多播组地址信息;
join_adr.imr_interface.s_addr 加入多播组的主机地址信息;
setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) join_adr, sizeof(join_adr));
...struct ip_mreq{struct in_addr imr_multiaddr; // 表示加入的多播组IP地址struct in_addr imr_interface; // socket所属主机的IP地址可以使用 INADDR_ANY
}
2--多播代码实例
发送端
// gcc news_sender.c -o news_sender
// ./news_sender 224.1.1.2 9190#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define TTL 64
#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}int main(int argc, char* argv[]){int send_sock;struct sockaddr_in mul_adr;int time_live TTL; // 初始化 TTL 大小FILE* fp;char buf[BUF_SIZE];if(argc ! 3){printf(Usage: %s GroupIP PORT\n, argv[0]);exit(1);}send_sock socket(PF_INET, SOCK_DGRAM, 0);memset(mul_adr, 0, sizeof(mul_adr));mul_adr.sin_family AF_INET;mul_adr.sin_addr.s_addr inet_addr(argv[1]); // 多播IPmul_adr.sin_port htons(atoi(argv[2])); // 多播端口setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*)time_live, sizeof(time_live));if((fp fopen(news.txt, r)) NULL){error_handling(fopen() error);}while(!feof(fp)){fgets(buf, BUF_SIZE, fp);sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr*)mul_adr, sizeof(mul_adr));sleep(2);}fclose(fp);close(send_sock);return 0;
}
接收端
// gcc news_receiver.c -o news_receiver
// ./news_receiver 224.1.1.2 9190
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}int main(int argc, char* argv[]){int recv_sock;int str_len;char buf[BUF_SIZE];struct sockaddr_in adr;struct ip_mreq join_adr;if(argc ! 3){printf(Usage: %s GroupIP PORT\n, argv[0]);exit(1);}recv_sock socket(PF_INET, SOCK_DGRAM, 0);memset(adr, 0, sizeof(adr));adr.sin_family AF_INET;adr.sin_addr.s_addr htonl(INADDR_ANY);adr.sin_port htons(atoi(argv[2])); // 多播端口if(bind(recv_sock, (struct sockaddr*) adr, sizeof(adr)) -1){error_handling(bind() error);}join_adr.imr_multiaddr.s_addr inet_addr(argv[1]); // 设置接收的多播地址join_adr.imr_interface.s_addr htonl(INADDR_ANY); // 设置本机地址// 设置 IP_ADD_MEMBERSHIP 可选项允许加入多播组setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)join_adr, sizeof(join_adr));while(1){str_len recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);if(str_len 0){break;}buf[str_len] 0;fputs(buf, stdout);}close(recv_sock);return 0;
} 3--广播 广播也可以实现一次性向多个主机发送数据但广播只能向同一网络中的主机传输数据广播基于 UDP 完成其根据 IP 地址的不同可以分为直接广播和本地广播 直接广播的 IP 地址中除了网络地址外其余主机地址全部设置为 1例如向网络地址 192.12.34. 中所有的主机传输数据时可以向 192.12.34.255 传输 本地广播中使用的 IP 地址限定为 255.255.255.255例如192.32.24网络中的主机向 255.255.255.255 传输数据时数据将传递到 192.32.24 网络中的所有主机 // 数据通信中使用的 IP 地址是与 UDP 示例的唯一区别
// 默认生成的 socket 会阻止广播因此需要使用以下伪代码更改默认设置
// 调用 setsockopt() 函数将 SO_BROADCAST 选项设置为 bcast 变量中的值 1
int send_sock;
int bcast 1;
...
send_sock socket(PF_INET, SOCK_DGRAM, 0);
...
setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void*) bcast, sizeof(bcast));
...
4--广播代码实例
发送端
// gcc news_sender_brd.c -o news_sender_brd
// ./news_sender_brd 255.255.255.255 9190#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}int main(int argc, char* argv[]){int send_sock;struct sockaddr_in broad_adr;FILE* fp;char buf[BUF_SIZE];int so_brd 1;if(argc ! 3){printf(Usage: %s Broadcast_IP PORT\n, argv[0]);exit(1);}send_sock socket(PF_INET, SOCK_DGRAM, 0);memset(broad_adr, 0, sizeof(broad_adr));broad_adr.sin_family AF_INET;broad_adr.sin_addr.s_addr inet_addr(argv[1]); // 广播IPbroad_adr.sin_port htons(atoi(argv[2])); // 广播端口// 允许数据广播setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void*)so_brd, sizeof(so_brd));if((fp fopen(news.txt, r)) NULL){error_handling(fopen() error);}while(!feof(fp)){fgets(buf, BUF_SIZE, fp);sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr*)broad_adr, sizeof(broad_adr));sleep(2);}close(send_sock);return 0;
}
接收端
// gcc news_receiver_brd.c -o news_receiver_brd
// ./news_receiver_brd 9190
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}int main(int argc, char* argv[]){int recv_sock;struct sockaddr_in adr;int str_len;char buf[BUF_SIZE];if(argc ! 2){printf(Usage: %s PORT\n, argv[0]);exit(1);}recv_sock socket(PF_INET, SOCK_DGRAM, 0);memset(adr, 0, sizeof(adr));adr.sin_family AF_INET;adr.sin_addr.s_addr htonl(INADDR_ANY);adr.sin_port htons(atoi(argv[1])); // 接收的广播端口if(bind(recv_sock, (struct sockaddr*) adr, sizeof(adr)) -1){error_handling(bind() error);}while(1){str_len recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);if(str_len 0){break;}buf[str_len] 0;fputs(buf, stdout);}close(recv_sock);return 0;
}