• 【项目 计网12】4.32UDP通信实现 4.33广播 4.34组播 4.35本地套接字通信



    4.32UDP通信实现

    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    udp_client.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/9a33040c7d40471594d952acaba17255.png)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    udp_server.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    4.33广播

    向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包含一个特殊的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的大小
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    bro_server.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(){
    	//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.193.255",&cliaddr.sin_addr.s_addr);
    
    	//4、通信
    	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);
    		sleep(1);
    	}
    	close(fd);
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    bro_client.c
    #include 
    #include 
    #include 
    #include 
    #include 
     
    int main() {
    
        // 1.创建一个通信的socket
        int fd = socket(PF_INET, SOCK_DGRAM, 0);
        if(fd == -1) {
            perror("socket");
            exit(-1);
        }   
    
        struct in_addr in;
    
        // 2.客户端绑定本地的IP和端口
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(9999);
        addr.sin_addr.s_addr = INADDR_ANY;
    
        int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
        if(ret == -1) {
            perror("bind");
            exit(-1);
        }
    
        // 3.通信
        while(1) {
            
            char buf[128];
            // 接收数据
            int num = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
            printf("server say : %s\n", buf);
    
        }
    
        close(fd);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    4.34组播

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    multi_server.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main() {
    
        // 1.创建一个通信的socket
        int fd = socket(PF_INET, SOCK_DGRAM, 0);
        if(fd == -1) {
            perror("socket");
            exit(-1);
        }   
    
        // 2.设置多播的属性,设置外出接口
        struct in_addr imr_multiaddr;
        // 初始化多播地址
        inet_pton(AF_INET, "239.0.0.10", &imr_multiaddr.s_addr);
        setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr_multiaddr, sizeof(imr_multiaddr));
        
        // 3.初始化客户端的地址信息
        struct sockaddr_in cliaddr;
        cliaddr.sin_family = AF_INET;
        cliaddr.sin_port = htons(9999);
        inet_pton(AF_INET, "239.0.0.10", &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);
            sleep(1);
        }
    
        close(fd);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    multi_client.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main() {
    
        // 1.创建一个通信的socket
        int fd = socket(PF_INET, SOCK_DGRAM, 0);
        if(fd == -1) {
            perror("socket");
            exit(-1);
        }   
    
        struct in_addr in;
        // 2.客户端绑定本地的IP和端口
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(9999);
        addr.sin_addr.s_addr = INADDR_ANY;
    
        int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
        if(ret == -1) {
            perror("bind");
            exit(-1); 
        }
    
        struct ip_mreq op;
        inet_pton(AF_INET, "239.0.0.10", &op.imr_multiaddr.s_addr);
        op.imr_interface.s_addr = INADDR_ANY;
    
        // 加入到多播组
        setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &op, sizeof(op));
    
        // 3.通信
        while(1) {
            
            char buf[128];
            // 接收数据
            int num = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
            printf("server say : %s\n", buf);
    
        }
    
        close(fd);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    4.35本地套接字通信

    本地套接字的作用:本地的进程间通信
    有关系的进程间的通信
    没有关系的进程间的通信
    本地套接字实现流程和网络套接字类似,一般采用TCP通信流程
    在这里插入图片描述

    //本地套接字通信的流程 -tcp
    //服务器端
    1、创建监听的套接字
    	int lfd=socket(AF_UNIX/AF_LOCAL,SOCK_STREAM,0);
    2、监听的套接字绑定本地的套接字文件->server端
    	struct sockaddr_un addr;
    	//绑定成之后,指定的sun_path中的套接字文件会自动生成
    	bind(lfd,addr,len);
    3、监听
    	listen(lfd,100);
    4、等待并接受连接请求
    	struct sockaddr_un cliaddr;
    	int len=sizeof(cliaddr);
    	int cfd=accept(lfd,&cliaddr,len);
    5、通信
    	接收数据:read/rev
    	发送数据:write/send
    6、关闭连接
    	close()
    
    //客户端的流程
    1、创建通信的套接字
    	int fd=socket(AF_UNIX/AF_LOCAL,SOCK_STREAM,0);
    2、监听的套接字绑定本地的IP端口
    	struct sockaddr_un addr;
    	//绑定成功之后,指定的sun_path中的套接字文件会自动生成
    	bind(lfd,addr,len);
    3、连接服务端
    	struct sockaddr_un serveraddr;
    	connect(fd,&serveraddr,sizeof(serveraddr));
    4、通信
    	接收数据:read/recv
    	发送数据:write/send
    5、关闭连接
    	close()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    //头文件:sys/un.h
    #define UNIX_PATH_MAX 108
    struct sockaddr_un{
    	sa_family_t sun_family;//地址族协议 af_local
    	char sun_path[UNIX_PATH_MAX];//套接字文件的路径,这是一个伪文件,大小永远=0 
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    ipc_server.c
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main() {
    
        unlink("server.sock");
    
        // 1.创建监听的套接字
        int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        if(lfd == -1) {
            perror("socket");
            exit(-1);
        }
    
        // 2.绑定本地套接字文件
        struct sockaddr_un addr;
        addr.sun_family = AF_LOCAL;
        strcpy(addr.sun_path, "server.sock");
        int ret = bind(lfd, (struct sockaddr *)&addr, sizeof(addr));
        if(ret == -1) {
            perror("bind");
            exit(-1);
        }
    
        // 3.监听
        ret = listen(lfd, 100);
        if(ret == -1) {
            perror("listen");
            exit(-1);
        }
    
        // 4.等待客户端连接
        struct sockaddr_un cliaddr;
        int len = sizeof(cliaddr);
        int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);
        if(cfd == -1) {
            perror("accept");
            exit(-1);
        }
    
        printf("client socket filename: %s\n", cliaddr.sun_path);
    
        // 5.通信
        while(1) {
    
            char buf[128];
            int len = recv(cfd, buf, sizeof(buf), 0);
    
            if(len == -1) {
                perror("recv");
                exit(-1);
            } else if(len == 0) {
                printf("client closed....\n");
                break;
            } else if(len > 0) {
                printf("client say : %s\n", buf);
                send(cfd, buf, len, 0);
            }
    
        }
    
        close(cfd);
        close(lfd);
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    ipc_client.c
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main() {
    
        unlink("client.sock");
    
        // 1.创建套接字
        int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        if(cfd == -1) {
            perror("socket");
            exit(-1);
        }
    
        // 2.绑定本地套接字文件
        struct sockaddr_un addr;
        addr.sun_family = AF_LOCAL;
        strcpy(addr.sun_path, "client.sock");
        int ret = bind(cfd, (struct sockaddr *)&addr, sizeof(addr));
        if(ret == -1) {
            perror("bind");
            exit(-1);
        }
    
        // 3.连接服务器
        struct sockaddr_un seraddr;
        seraddr.sun_family = AF_LOCAL;
        strcpy(seraddr.sun_path, "server.sock");
        ret = connect(cfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
        if(ret == -1) {
            perror("connect");
            exit(-1);
        }
    
        // 4.通信
        int num = 0;
        while(1) {
    
            // 发送数据
            char buf[128];
            sprintf(buf, "hello, i am client %d\n", num++);
            send(cfd, buf, strlen(buf) + 1, 0);
            printf("client say : %s\n", buf);
    
            // 接收数据
            int len = recv(cfd, buf, sizeof(buf), 0);
    
            if(len == -1) {
                perror("recv");
                exit(-1);
            } else if(len == 0) {
                printf("server closed....\n");
                break;
            } else if(len > 0) {
                printf("server say : %s\n", buf);
            }
    
            sleep(1);
    
        }
    
        close(cfd);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
  • 相关阅读:
    校园综合服务平台V3.9.2 源码修复大部分已知BUG
    「运维有小邓」AD域委派
    DAMA-DMBOK2重点知识整理CDGA/CDGP——第16章 数据管理组织与角色期望
    2023年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
    自动化运维?看看Python怎样完成自动任务调度⛵
    C++如何进行字符串分割,C++如何按照空格对字符串进行解析,C++如何按照逗号对字符串解析
    分享自己平时使用的socket多客户端通信的代码技术点和软件使用
    C# 中的多线程和异步编程
    [NOIP2000 提高组]-乘积最大:隔板法-DFS搜索-Go语言
    【探索AI】二十四 深度学习之第7周:深度学习在实际应用中的案例
  • 原文地址:https://blog.csdn.net/weixin_43896452/article/details/132527279