欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 网络编程(学习)2024.9.3

网络编程(学习)2024.9.3

2024/10/24 10:18:30 来源:https://blog.csdn.net/qq_60450758/article/details/141903990  浏览:    关键词:网络编程(学习)2024.9.3

目录

UDP多点通信

广播

理论

发送端--相当于udp客户端

接收端--相当于udp服务器

组播

理论

发送端

接收端

UDP多点通信

广播

理论

前面介绍的数据包发送方式只有一个接受方,称为单播
如果同时发给局域网中的所有主机,称为广播
只有用户数据报(使用UDP协议)套接字才能广播
一般被设计成局域网搜索协议
广播地址:以192.168.1.0 (255.255.255.0) 网段为例,最大的主机地址192.168.1.255代表该网段的广播地址
发到该地址的数据包被所有的主机接收     

发送端--相当于udp客户端

1.socket;
2.setsockopt         允许发送广播
3.填充结构体
        a.IP:广播地址
        b.端口号,应该与接收端的端口号
4.发送广播

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("创建套接字失败\n");return -1;}// 2.允许发送广播int flag = 1;socklen_t len = sizeof(flag);setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &flag, len);// 3.填充结构体struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(8888);saddr.sin_addr.s_addr = inet_addr("192.168.50.255");socklen_t addrlen = sizeof(saddr);#define N 64char buf[N];while (1){memset(buf, 0, N);printf("请输入要输入的数据:");scanf("%s", buf);getchar();sendto(sockfd, buf, N, 0, (struct sockaddr *)&saddr, addrlen);}close(sockfd);return 0;
}

接收端--相当于udp服务器

1.socket;
2.填充结构体
        a.IP:(0.0.0.0):本机所有可用IP--局域网IP、本地回环、广播地址、已加入的多播组
        b.port:端口号 8888
3.bind
4.recvfrom

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("创建套接字失败\n");return -1;}// 2.bind绑定IP和Port端口号struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));saddr.sin_addr.s_addr = inet_addr("0.0.0.0");socklen_t addrlen = sizeof(saddr);if (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){perror("bind失败");return -1;}printf("bind成功\n");// 3.接收消息
#define N 64char buf[N];while (1){int ret = recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&caddr, &addrlen);if (ret < 0){perror("接收消息失败\n");close(sockfd);return -1;}else{printf("客户端ip:%s:%s\n", inet_ntoa(caddr.sin_addr), buf);}}close(sockfd);return 0;
}

组播

理论

接收方是局域网里的一部分
好处:避免了像广播那样带来的比较大的网络负载

组播地址:224.0.0.1~~239.255.255.254

发送端

1、socket;
2、填充结构体
        a)IP:组播IP 
        b)port
3、发送

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("创建套接字失败\n");return -1;}//2.填充结构体struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(8888);saddr.sin_addr.s_addr = inet_addr("224.0.0.3");socklen_t addrlen = sizeof(saddr);#define N 64char buf[N];while (1){memset(buf, 0, N);printf("请输入要输入的数据:");scanf("%s", buf);getchar();sendto(sockfd, buf, N, 0, (struct sockaddr *)&saddr, addrlen);}close(sockfd);return 0;
}


接收端

1、socket
2、setsockopt    加入多播组
3、填充结构体
        a)ip:0.0.0.0
        b)PORT
4、bind
5、recvfrom

关于setsockopt要填充的结构体
struct ip_mreq
{
    struct  in_addr  imr_multiaddr;   /* 指定多播组IP */
    struct  in_addr  imr_interface;   /* 本地网卡地址,通常指定为 INADDR_ANY--0.0.0.0*/};
}

struct ip_mreq mreq;
//bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("创建套接字失败\n");return -1;}// 加入多播组struct ip_mreq mreq;// bzero(&mreq, sizeof(mreq));mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.3");mreq.imr_interface.s_addr = INADDR_ANY;setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));saddr.sin_addr.s_addr = inet_addr("0.0.0.0");socklen_t addrlen = sizeof(saddr);if (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){perror("bind失败");return -1;}printf("bind成功\n");
// 3.接收消息
#define N 64char buf[N];while (1){int ret = recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&caddr, &addrlen);if (ret < 0){perror("接收消息失败\n");close(sockfd);return -1;}else{printf("客户端ip:%s:%s\n", inet_ntoa(caddr.sin_addr), buf);}}close(sockfd);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com