网络编程(学习)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;
}
相关推荐
速盾cdn1 小时前
速盾:CDN是否支持屏蔽IP?
网络·网络协议·tcp/ip
yaoxin5211231 小时前
第二十七章 TCP 客户端 服务器通信 - 连接管理
服务器·网络·tcp/ip
内核程序员kevin1 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
PersistJiao2 小时前
Spark 分布式计算中网络传输和序列化的关系(一)
大数据·网络·spark
黑客Ash5 小时前
【D01】网络安全概论
网络·安全·web安全·php
->yjy5 小时前
计算机网络(第一章)
网络·计算机网络·php
朝九晚五ฺ5 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
摘星星ʕ•̫͡•ʔ6 小时前
计算机网络 第三章:数据链路层(关于争用期的超详细内容)
网络·计算机网络
.Ayang7 小时前
SSRF漏洞利用
网络·安全·web安全·网络安全·系统安全·网络攻击模型·安全架构