网络编程(学习)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.发送广播

cpp 复制代码
#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 64
    char 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

cpp 复制代码
#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 64
    char 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、发送

cpp 复制代码
#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 64
    char 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));

cpp 复制代码
#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 64
    char 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;
}
相关推荐
sealaugh322 小时前
aws(学习笔记第四十八课) appsync-graphql-dynamodb
笔记·学习·aws
2501_915921432 小时前
iOS IPA 混淆实测分析:从逆向视角验证加固效果与防护流程
websocket·网络协议·tcp/ip·http·网络安全·https·udp
2501_915918412 小时前
打造可观测的 iOS CICD 流程:调试、追踪与质量保障全记录
websocket·网络协议·tcp/ip·http·网络安全·https·udp
水木兰亭2 小时前
数据结构之——树及树的存储
数据结构·c++·学习·算法
鱼摆摆拜拜3 小时前
第 3 章:神经网络如何学习
人工智能·神经网络·学习
aha-凯心3 小时前
vben 之 axios 封装
前端·javascript·学习
Absinthe_苦艾酒4 小时前
计算机网络(三)传输层TCP
网络·tcp/ip·计算机网络
GLAB-Mary4 小时前
AI会取代网络工程师吗?理解AI在网络安全中的角色
网络·人工智能·web安全
敲敲敲-敲代码5 小时前
【ArcGIS10.2】网络数据集构建---最短路径分析
网络·arcgis
2501_915909066 小时前
调试 WebView 旧资源缓存问题:一次从偶发到复现的实战经历
websocket·网络协议·tcp/ip·http·网络安全·https·udp