广播:
广播1.ubuntu@ubuntu:~/yuyu/yu/11$ cat broadSnd.c #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> #include <string.h> #include <unistd.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define CLI_PORT 6666 #define CLI_Ip "192.168.8.187" #define SER_PORT 8888 #define SER_IP "192.168.8.255" int main(int argc, const char *argv[]) { //创建套接字 int sfd = socket(AF_INET, SOCK_DGRAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //设置允许广播 int broad = 1; if(setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0) { ERR_MSG("setsockopt"); return -1; } //绑定客户端的地址信息结构体到套接字文件描述符上,非必须绑定 //填充接收端地址信息结构体,真实的地址信息结构体根据地址族规定 //AF_INET : man 7 ip, //由于下面的sendto要发送给接收,所以需要先填充接收端的地址信息结构体 //供给下面的sendto函数使用; struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(SER_PORT); //服务器的端口 sin.sin_addr.s_addr = inet_addr(SER_IP); //广播IP //注意, 切换网络环境后, IP地址是会改变的 char buf[128] = ""; int i = 0; while(1) { bzero(buf, sizeof(buf)); sprintf(buf, "yuyu wow %d", ++i); sleep(1); //发送,数据给服务器 #if 0 printf("请输入>>>"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = 0; #endif if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("sendto"); return -1; } printf("6666666666666\n"); } //关闭文件描述符 close(sfd); return 0; }
广播2 ubuntu@ubuntu:~/yuyu/yu/11$ cat broadRcv.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define PORT 8888 #define IP "192.168.8.255" int main(int argc, const char *argv[]) { //创建报式套接字 int sfd = socket(AF_INET, SOCK_DGRAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //填充地址信息结构体,真是的地址信息结构体根据地址族制定 //AF_INET : man 7 ip struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(PORT); //端口号的网络字节序;1024~49151 sin.sin_addr.s_addr = inet_addr(IP); //广播IP //注意,切换网络环境后,IP地址是会改变的 //绑定服务器的地址信息结构体到套接字文件描述符上,必须绑定 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("888888888yuyuyuyu\n"); ssize_t res = 0; char buf[128] = ""; struct sockaddr_in cin; //存储数据包的来源 socklen_t addrlen = sizeof(cin); while(1) { bzero(buf, sizeof(buf)); //接收, 接收信息的同事, 接受该数据包从谁那里来 res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen); if(res < 0) { ERR_MSG("recvfrom"); return -1; } printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf); } //关闭文件描述符 close(sfd); return 0; } ubuntu@ubuntu:~/yuyu/yu/11$
2.组播
组播1ubuntu@ubuntu:~/yuyu/yu/11$ cat memberSnd.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define CLI_PORT 6666 #define CLI_IP "192.168.8.255" #define SER_PORT 8888 #define SER_IP "224.1.2.3" int main(int argc, const char *argv[]) { //创建报式套接字 int sfd = socket(AF_INET, SOCK_DGRAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //填充地址信息结构体,真是的地址信息结构体根据地址族制定 //AF_INET : man 7 ip struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(SER_PORT); //端口号的网络字节序;1024~49151 sin.sin_addr.s_addr = inet_addr(SER_IP); //组播IP //注意,切换网络环境后,IP地址是会改变的 #if 0 //绑定服务器的地址信息结构体到套接字文件描述符上,必须绑定 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("77777777\n"); ssize_t res = 0; char buf[128] = ""; struct sockaddr_in cin; //存储数据包的来源 socklen_t addrlen = sizeof(cin); #endif char buf[128] = ""; while(1) { bzero(buf,sizeof(buf)); //发送,数据给服务器 printf("请输入>>>"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = 0; if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("sendto"); return -1; } printf("sendto success\n"); } //关闭文件描述符 close(sfd); return 0; } ubuntu@ubuntu:~/yuyu/yu/11$
组播2 ubuntu@ubuntu:~/yuyu/yu/11$ cat menberRcv.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> #include <net/if.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define PORT 8888 #define IP "192.168.8.187" #define GRP_IP "224.1.2.3" int main(int argc, const char *argv[]) { //创建报式套接字 int sfd = socket(AF_INET, SOCK_DGRAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //加入多播组setsockopt struct ip_mreqn mq; mq.imr_multiaddr.s_addr = inet_addr(GRP_IP); //组播IP mq.imr_address.s_addr = inet_addr(IP); //本机IP mq.imr_ifindex = if_nametoindex("ens37"); //设备索引导 if(setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0) { ERR_MSG("setsockopt"); return -1; } printf("加入多播组成功\n"); //填充地址信息结构体,真是的地址信息结构体根据地址族规定 //AF_INET : man 7 ip struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(PORT); //端口号的网络字节序;1024~49151 sin.sin_addr.s_addr = inet_addr(GRP_IP); //组播IP //注意, 切换网络环境后,IP地址是会改变的 //绑定服务器的地址信息结构体到套接字文件描述符上,必须绑定 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("hhhhhhhhh wow\n"); ssize_t res = 0; char buf[128] = ""; struct sockaddr_in cin; //存储数据包的来源 socklen_t addrlen = sizeof(cin); while(1) { bzero(buf, sizeof(buf)); //接收,接受信息的同时,接收该数据包从谁哪里来 res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen); if(res < 0) { ERR_MSG("recvfrom"); return -1; } printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf); } //关闭文件描述符 close(sfd); return 0; } ubuntu@ubuntu:~/yuyu/yu/11$