目录
数据包发送方式只有一个接受方,称为单播
如果同时发给局域网中的所有主机,称为广播
只有用户数据报(使用UDP协议)套接字才能广播
广播的实现

sender.c
- #include
- #include
- #include
- #include
/* superset of previous */ - #include
- #include
- #include
- #include
- #include
-
- #define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
- typedef struct sockaddr Addr;
- typedef struct sockaddr_in Addr_in;
-
- int main(int argc, char *argv[])
- {
- int fd = -1;
- Addr_in peeraddr;
- socklen_t peerlen = sizeof(peeraddr);
- char buf[BUFSIZ] = {};
- /*参数检查*/
- if(argc < 3){
- fprintf(stderr, "%s
" , argv[0]); - exit(EXIT_FAILURE);
- }
- /*创建套接字*/
- if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
- ErrExit("socket");
-
- /*允许广播*/
- int on = 1;
- setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
-
- /*设置通信结构体*/
- peeraddr.sin_family = AF_INET;
- peeraddr.sin_port = htons(atoi(argv[2]));
- if(!inet_aton(argv[1], &peeraddr.sin_addr) ){
- fprintf(stderr, "Invalid address\n");
- exit(EXIT_FAILURE);
- }
- while(1){
- fgets(buf, BUFSIZ, stdin);
- sendto(fd, buf, strlen(buf)+1, 0, (Addr *)&peeraddr, peerlen);
- }
- return 0;
- }
receiver.c
- #include
- #include
- #include
- #include
/* superset of previous */ - #include
- #include
- #include
- #include
-
- #define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
- typedef struct sockaddr Addr;
- typedef struct sockaddr_in Addr_in;
-
- int main(int argc, char *argv[])
- {
- int fd = -1;
- Addr_in myaddr, peeraddr;
- socklen_t peerlen = sizeof(peeraddr);
- char buf[BUFSIZ] = {};
- /*参数检查*/
- if(argc < 3){
- fprintf(stderr, "%s
" , argv[0]); - exit(EXIT_FAILURE);
- }
- /*创建套接字*/
- if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
- ErrExit("socket");
- /*设置通信结构体*/
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(atoi(argv[2]));
- if(!inet_aton(argv[1], &myaddr.sin_addr) ){
- fprintf(stderr, "Invalid address\n");
- exit(EXIT_FAILURE);
- }
- /*绑定通信结构体*/
- if( bind(fd, (Addr *)&myaddr, sizeof(Addr_in)) )
- ErrExit("bind");
- while(1){
- recvfrom(fd, buf, BUFSIZ, 0, (Addr *)&peeraddr, &peerlen);
- printf("[%s:%d]%s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);
- }
- return 0;
- }

- struct ip_mreqn {
- struct in_addr imr_multiaddr; /*IP 组播组地址*/
- struct in_addr imr_address; /*本地接口的IP地址*/
- int imr_ifindex; /*本地网卡的编号*/
- }
- if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){
- perror("setsockopt");
- exit(0);
- }
sender.c
- #include
- #include
- #include
- #include
/* superset of previous */ - #include
- #include
- #include
- #include
- #include
-
- #define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
- typedef struct sockaddr Addr;
- typedef struct sockaddr_in Addr_in;
-
- int main(int argc, char *argv[])
- {
- int fd = -1;
- Addr_in peeraddr;
- socklen_t peerlen = sizeof(peeraddr);
- char buf[BUFSIZ] = {};
- /*参数检查*/
- if(argc < 3){
- fprintf(stderr, "%s
" , argv[0]); - exit(EXIT_FAILURE);
- }
- /*创建套接字*/
- if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
- ErrExit("socket");
-
- /*设置通信结构体*/
- peeraddr.sin_family = AF_INET;
- peeraddr.sin_port = htons(atoi(argv[2]));
- if(!inet_aton(argv[1], &peeraddr.sin_addr) ){
- fprintf(stderr, "Invalid address\n");
- exit(EXIT_FAILURE);
- }
- while(1){
- fgets(buf, BUFSIZ, stdin);
- sendto(fd, buf, strlen(buf)+1, 0, (Addr *)&peeraddr, peerlen);
- }
- return 0;
- }
receiver.c
- #include
- #include
- #include
- #include
/* superset of previous */ - #include
- #include
- #include
- #include
-
- #define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
- typedef struct sockaddr Addr;
- typedef struct sockaddr_in Addr_in;
-
- int main(int argc, char *argv[])
- {
- int fd = -1;
- Addr_in myaddr, peeraddr;
- socklen_t peerlen = sizeof(peeraddr);
- struct ip_mreqn mreq;
- char buf[BUFSIZ] = {};
- /*参数检查*/
- if(argc < 3){
- fprintf(stderr, "%s
" , argv[0]); - exit(EXIT_FAILURE);
- }
- /*创建套接字*/
- if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
- ErrExit("socket");
- /*加入多播组*/
- bzero(&mreq, sizeof(mreq) );
- if(!inet_aton(argv[1], &mreq.imr_multiaddr) ){
- fprintf(stderr, "Invalid address\n");
- exit(EXIT_FAILURE);
- }
- if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){
- perror("setsockopt");
- exit(0);
- }
-
- /*设置通信结构体*/
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(atoi(argv[2]));
- if(!inet_aton(argv[1], &myaddr.sin_addr) ){
- fprintf(stderr, "Invalid address\n");
- exit(EXIT_FAILURE);
- }
- /*绑定通信结构体*/
- if( bind(fd, (Addr *)&myaddr, sizeof(Addr_in)) )
- ErrExit("bind");
- while(1){
- recvfrom(fd, buf, BUFSIZ, 0, (Addr *)&peeraddr, &peerlen);
- printf("[%s:%d]%s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);
- }
- return 0;
- }
