UDP通信实现
- #include <sys/types.h>
- #include <sys/socket.h>
- ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
- const struct sockaddr *dest_addr, socklen_t addrlen);
- - 参数:
- struct sockaddr *src_addr, socklen_t *addrlen)
- - sockfd : 通信的fd
- - buf : 要发送的数据
- - len : 发送数据的长度
- - flags : 0
- - dest_addr : 通信的另外一端的地址信息
- - addrlen : 地址的内存大小
-
- ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
- ;
- - 参数:
- - sockfd : 通信的fd
- - buf : 接收数据的数组
- - len : 数组的大小
- - flags : 0
- - src_addr : 用来保存另外一端的地址信息,不需要可以指定为NULL
- - addrlen : 地址的内存大小
复制代码 案例
udp_server.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <arpa/inet.h>
- int main() {
- // 1.创建一个通信的socket
- int fd = socket(PF_INET, SOCK_DGRAM, 0);
-
- if(fd == -1) {
- perror("socket");
- exit(-1);
- }
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(9999);
- addr.sin_addr.s_addr = INADDR_ANY;
- // 2.绑定
- int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
- if(ret == -1) {
- perror("bind");
- exit(-1);
- }
- // 3.通信
- while(1) {
- char recvbuf[128];
- char ipbuf[16];
- struct sockaddr_in cliaddr;
- int len = sizeof(cliaddr);
- // 接收数据
- int num = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&cliaddr, &len);
- printf("client IP : %s, Port : %d\n",
- inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
- ntohs(cliaddr.sin_port));
- printf("client say : %s\n", recvbuf);
- // 发送数据
- sendto(fd, recvbuf, strlen(recvbuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
- }
- close(fd);
- return 0;
- }
复制代码 udp_client.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <arpa/inet.h>
- int main() {
- // 1.创建一个通信的socket
- int fd = socket(PF_INET, SOCK_DGRAM, 0);
-
- if(fd == -1) {
- perror("socket");
- exit(-1);
- }
- // 服务器的地址信息
- struct sockaddr_in saddr;
- saddr.sin_family = AF_INET;
- saddr.sin_port = htons(9999);
- inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr.s_addr);
- int num = 0;
- // 3.通信
- while(1) {
- // 发送数据
- char sendBuf[128];
- sprintf(sendBuf, "hello , i am client %d \n", num++);
- sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&saddr, sizeof(saddr));
- // 接收数据
- int num = recvfrom(fd, sendBuf, sizeof(sendBuf), 0, NULL, NULL);
- printf("server say : %s\n", sendBuf);
- sleep(1);
- }
- close(fd);
- return 0;
- }
复制代码 广播
向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包罗一个特殊的IP地址,这个IP中子网内主机标记部分的二进制全部为1。
a.只能在局域网中使用。
b.客户端需要绑定服务器广播使用的端口,才可以接收到广播消息。
- // 设置广播属性的函数
- int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t
- optlen);
- - sockfd : 文件描述符
- - level : SOL_SOCKET
- - optname : SO_BROADCAST
- - optval : int类型的值,为1表示允许广播
- - optlen : optval的大小
复制代码 案例
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <arpa/inet.h>
- /**
- * 主函数:实现UDP广播发送消息
- * 创建一个UDP套接字,并配置为广播类型,然后循环向指定广播地址发送消息。
- */
- int main() {
- // 创建一个UDP类型的套接字
- // 1.创建一个通信的socket
- int fd = socket(PF_INET, SOCK_DGRAM, 0);
- if(fd == -1) {
- perror("socket");
- exit(-1);
- }
- // 设置套接字选项,允许发送广播消息
- // 2.设置广播属性,设置为广播就不需要再绑定了,因为只发送数据
- int op = 1;
- setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &op, sizeof(op));
-
- // 初始化客户端地址结构体,设置为广播地址
- // 3.创建一个广播的地址
- struct sockaddr_in cliaddr;
- cliaddr.sin_family = AF_INET;
- cliaddr.sin_port = htons(9999);
- inet_pton(AF_INET, "192.168.220.255", &cliaddr.sin_addr.s_addr);
- // 循环发送消息
- // 3.通信
- int num = 0;
- while(1) {
- // 准备发送的消息,包含消息编号
- char sendBuf[128];
- sprintf(sendBuf, "hello, client....%d\n", num++);
- // 发送消息到广播地址
- // 发送数据
- sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
- printf("广播的数据:%s\n", sendBuf);
- // 休眠1秒后继续发送
- sleep(1);
- }
- // 关闭套接字
- close(fd);
- return 0;
- }
复制代码 组播(多播)
单播地址标识单个 IP 接口,广播地址标识某个子网的所有 IP 接口,多播地址标识一组 IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部),多播则意在两者之间提供一种折中方案。多播数据报只应该由对它感爱好的接口接收,也就是说由运行相应多播会话应用系统的主机上的接口接收。另外,广播一样平常局限于局域网内使用,而多播则既可以用于局域网,也可以跨广域网使用。
a.组播既可以用于局域网,也可以用于广域网
b.客户端需要参加多播组,才能接收到多播的数据
组播地址
IP 多播通信必须依赖于 IP 多播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255 ,
并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:
- int setsockopt(int sockfd, int level, int optname,const void *optval,
- socklen_t optlen);
- // 服务器设置多播的信息,外出接口
- - level : IPPROTO_IP
- - optname : IP_MULTICAST_IF
- - optval : struct in_addr
- // 客户端加入到多播组:
- - level : IPPROTO_IP
- - optname : IP_ADD_MEMBERSHIP
- - optval : struct ip_mreq
- struct ip_mreq
- {
- /* IP multicast address of group. */
- struct in_addr imr_multiaddr; // 组播的IP地址
- /* Local IP address of interface. */
- struct in_addr imr_interface; // 本地的IP地址
- };
- typedef uint32_t in_addr_t;
- struct in_addr
- {
- in_addr_t s_addr;
- };
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |