UDP通信 单播,广播,组播

打印 上一主题 下一主题

主题 1042|帖子 1042|积分 3126

UDP通信实现

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
  4. const struct sockaddr *dest_addr, socklen_t addrlen);
  5. - 参数:
  6. struct sockaddr *src_addr, socklen_t *addrlen)
  7.            - sockfd : 通信的fd
  8.            - buf : 要发送的数据
  9.            - len : 发送数据的长度
  10.            - flags : 0
  11.            - dest_addr : 通信的另外一端的地址信息
  12.            - addrlen : 地址的内存大小
  13.                
  14. ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
  15. ;
  16. - 参数:
  17. - sockfd : 通信的fd
  18. - buf : 接收数据的数组
  19. - len : 数组的大小
  20. - flags : 0
  21. - src_addr : 用来保存另外一端的地址信息,不需要可以指定为NULL
  22. - addrlen : 地址的内存大小
复制代码
案例

udp_server.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <arpa/inet.h>
  6. int main() {
  7.     // 1.创建一个通信的socket
  8.     int fd = socket(PF_INET, SOCK_DGRAM, 0);
  9.    
  10.     if(fd == -1) {
  11.         perror("socket");
  12.         exit(-1);
  13.     }   
  14.     struct sockaddr_in addr;
  15.     addr.sin_family = AF_INET;
  16.     addr.sin_port = htons(9999);
  17.     addr.sin_addr.s_addr = INADDR_ANY;
  18.     // 2.绑定
  19.     int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
  20.     if(ret == -1) {
  21.         perror("bind");
  22.         exit(-1);
  23.     }
  24.     // 3.通信
  25.     while(1) {
  26.         char recvbuf[128];
  27.         char ipbuf[16];
  28.         struct sockaddr_in cliaddr;
  29.         int len = sizeof(cliaddr);
  30.         // 接收数据
  31.         int num = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&cliaddr, &len);
  32.         printf("client IP : %s, Port : %d\n",
  33.             inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
  34.             ntohs(cliaddr.sin_port));
  35.         printf("client say : %s\n", recvbuf);
  36.         // 发送数据
  37.         sendto(fd, recvbuf, strlen(recvbuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
  38.     }
  39.     close(fd);
  40.     return 0;
  41. }
复制代码
udp_client.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <arpa/inet.h>
  6. int main() {
  7.     // 1.创建一个通信的socket
  8.     int fd = socket(PF_INET, SOCK_DGRAM, 0);
  9.    
  10.     if(fd == -1) {
  11.         perror("socket");
  12.         exit(-1);
  13.     }   
  14.     // 服务器的地址信息
  15.     struct sockaddr_in saddr;
  16.     saddr.sin_family = AF_INET;
  17.     saddr.sin_port = htons(9999);
  18.     inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr.s_addr);
  19.     int num = 0;
  20.     // 3.通信
  21.     while(1) {
  22.         // 发送数据
  23.         char sendBuf[128];
  24.         sprintf(sendBuf, "hello , i am client %d \n", num++);
  25.         sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&saddr, sizeof(saddr));
  26.         // 接收数据
  27.         int num = recvfrom(fd, sendBuf, sizeof(sendBuf), 0, NULL, NULL);
  28.         printf("server say : %s\n", sendBuf);
  29.         sleep(1);
  30.     }
  31.     close(fd);
  32.     return 0;
  33. }
复制代码
广播

向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包罗一个特殊的IP地址,这个IP中子网内主机标记部分的二进制全部为1。
a.只能在局域网中使用。
b.客户端需要绑定服务器广播使用的端口,才可以接收到广播消息。


  1. // 设置广播属性的函数
  2. int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t
  3. optlen);
  4. - sockfd : 文件描述符
  5. - level : SOL_SOCKET
  6. - optname : SO_BROADCAST
  7. - optval : int类型的值,为1表示允许广播
  8. - optlen : optval的大小
复制代码
案例

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <arpa/inet.h>
  6. /**
  7. * 主函数:实现UDP广播发送消息
  8. * 创建一个UDP套接字,并配置为广播类型,然后循环向指定广播地址发送消息。
  9. */
  10. int main() {
  11.     // 创建一个UDP类型的套接字
  12.     // 1.创建一个通信的socket
  13.     int fd = socket(PF_INET, SOCK_DGRAM, 0);
  14.     if(fd == -1) {
  15.         perror("socket");
  16.         exit(-1);
  17.     }   
  18.     // 设置套接字选项,允许发送广播消息
  19.     // 2.设置广播属性,设置为广播就不需要再绑定了,因为只发送数据
  20.     int op = 1;
  21.     setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &op, sizeof(op));
  22.    
  23.     // 初始化客户端地址结构体,设置为广播地址
  24.     // 3.创建一个广播的地址
  25.     struct sockaddr_in cliaddr;
  26.     cliaddr.sin_family = AF_INET;
  27.     cliaddr.sin_port = htons(9999);
  28.     inet_pton(AF_INET, "192.168.220.255", &cliaddr.sin_addr.s_addr);
  29.     // 循环发送消息
  30.     // 3.通信
  31.     int num = 0;
  32.     while(1) {
  33.         // 准备发送的消息,包含消息编号
  34.         char sendBuf[128];
  35.         sprintf(sendBuf, "hello, client....%d\n", num++);
  36.         // 发送消息到广播地址
  37.         // 发送数据
  38.         sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
  39.         printf("广播的数据:%s\n", sendBuf);
  40.         // 休眠1秒后继续发送
  41.         sleep(1);
  42.     }
  43.     // 关闭套接字
  44.     close(fd);
  45.     return 0;
  46. }
复制代码
组播(多播)

单播地址标识单个 IP 接口,广播地址标识某个子网的所有 IP 接口,多播地址标识一组 IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部),多播则意在两者之间提供一种折中方案。多播数据报只应该由对它感爱好的接口接收,也就是说由运行相应多播会话应用系统的主机上的接口接收。另外,广播一样平常局限于局域网内使用,而多播则既可以用于局域网,也可以跨广域网使用。
a.组播既可以用于局域网,也可以用于广域网
b.客户端需要参加多播组,才能接收到多播的数据

组播地址
IP 多播通信必须依赖于 IP 多播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255 ,
并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:

  1. int setsockopt(int sockfd, int level, int optname,const void *optval,
  2. socklen_t optlen);
  3. // 服务器设置多播的信息,外出接口
  4. - level : IPPROTO_IP
  5. - optname : IP_MULTICAST_IF
  6. - optval : struct in_addr
  7. // 客户端加入到多播组:
  8. - level : IPPROTO_IP
  9. - optname : IP_ADD_MEMBERSHIP
  10. - optval : struct ip_mreq
  11. struct ip_mreq
  12. {
  13. /* IP multicast address of group. */
  14. struct in_addr imr_multiaddr; // 组播的IP地址
  15. /* Local IP address of interface. */
  16. struct in_addr imr_interface; // 本地的IP地址
  17. };
  18. typedef uint32_t in_addr_t;
  19. struct in_addr
  20. {
  21. in_addr_t s_addr;
  22. };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表