基于UDP的网络客户端和服务端模型IO函数

服务器端

udp_server.c

#include <stdio.h>            // 引入标准输入输出库  
#include <sys/types.h>        // 引入基本系统数据类型  
#include <sys/socket.h>       // 引入socket编程相关的库  
#include <netinet/in.h>       // 引入网络地址相关的库  
#include <arpa/inet.h>        // 引入网络地址转换等函数  
#include <unistd.h>           // 引入UNIX标准函数定义  
#include <string.h>           // 引入字符串操作函数  
  
#define BUF_SIZE 20           // 定义缓冲区大小为20字节  
  
int main(int argc, const char *argv[])  
{  
    int iServer = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个IPv4的UDP socket  
    if(-1 == iServer){  
        puts("----------1、create socket error!"); // 如果socket创建失败,打印错误消息  
        return -1;                                // 并返回-1退出程序  
    }  
    puts("----------1、create socket ok!");        // 如果socket创建成功,打印成功消息  
  
    struct sockaddr_in stServer;                  // 定义一个服务器地址结构体  
    stServer.sin_family = AF_INET;                // 设置地址族为IPv4  
    stServer.sin_port = htons(6666);              // 设置服务器端口为6666,使用htons将主机字节序转换为网络字节序  
    stServer.sin_addr.s_addr = inet_addr("0.0.0.0"); // 设置服务器IP地址为0.0.0.0,表示监听所有可用的网络接口  
  
    int ret = bind(iServer, (struct sockaddr *)&stServer, sizeof(struct sockaddr)); // 绑定socket到指定的地址和端口  
    if(-1 == ret){  
        puts("----------2、bind error!"); // 如果绑定失败,打印错误消息  
        return -1;                        // 并返回-1退出程序  
    }  
    puts("----------2、bind ok!");        // 如果绑定成功,打印成功消息  
  
    // 开始接收和发送数据  
    char buf[BUF_SIZE] = {0};             // 定义一个缓冲区,并初始化为0  
    struct sockaddr_in stClient;          // 定义一个客户端地址结构体,用于接收客户端的地址信息  
    socklen_t len = sizeof(struct sockaddr); // 定义socklen_t类型的变量,用于存储地址结构的长度  
  
    while(1){ // 无限循环,持续接收和发送数据  
        memset(buf, 0, BUF_SIZE); // 每次循环开始时,清空缓冲区  
  
        // 从客户端接收数据  
        if(recvfrom(iServer, buf, BUF_SIZE, 0, (struct sockaddr *)&stClient, &len) > 0){  
            // 如果接收成功(返回值大于0),则打印接收到的数据和客户端地址信息  
            printf("recvfrom Client ok! data:%s from %s:%d\r\n", buf, inet_ntoa(stClient.sin_addr), ntohs(stClient.sin_port));  
  
            // 将接收到的数据发送回客户端  
            sendto(iServer, buf, strlen(buf), 0, (struct sockaddr *)&stClient, len);  
            // 注意:这里使用strlen(buf)可能不安全,因为如果接收到的数据包含'\0',strlen会提前结束。  
            // 更安全的做法是使用recvfrom的返回值作为要发送的数据长度。  
        }  
    }  
  
    // 注意:由于程序使用了无限循环,所以正常情况下不会执行到这里。  
    // 如果要正常退出,可以在接收数据时加入某种退出条件,如接收到特定的命令或信号。  
  
    return 0; // 程序正常退出,但由于上面的无限循环,这里实际上不会被执行到。  
}
注意:

在使用recvfrom和sendto时,应该检查接收到的数据长度,并使用这个长度来发送数据,而不是简单地使用strlen(buf)。因为recvfrom可能会接收到包含'\0'字符的数据,这会导致strlen(buf)提前结束。
在无限循环中,应该加入一种机制来允许程序在特定条件下退出,例如接收到特定的命令或信号。
使用inet_ntoa函数将客户端的IP地址从网络字节序转换为点分十进制格式,并打印出来,这样可以看到是哪个客户端发送了数据。
socklen_t类型用于存储地址结构的长度,这是必须的,因为不同的系统可能有不同大小的地址结构。

客户端

udp_client.c

这是一个简单的UDP客户端程序,用于向指定的服务器发送数据,并尝试从同一地址接收数据(但通常UDP不是面向连接的,所以接收数据的操作可能不是从同一个服务器或端口来的)。
#include <stdio.h>  // 标准输入输出库  
#include <stdlib.h> // 标准库,包含exit等函数  
#include <string.h> // 字符串处理库  
#include <unistd.h> // Unix标准库,包含fgets等函数  
#include <arpa/inet.h> // 网络地址转换库  
#include <sys/types.h> // 数据类型定义  
#include <sys/socket.h> // 套接字库  
#include <netinet/in.h> // 网络接口,地址转换等函数  
  
#define SERVER_IP "0.0.0.0" // 服务器IP地址,但"0.0.0.0"通常用于监听所有网络接口,这里作为客户端可能不合适  
#define SERVER_PORT 6666     // 服务器端口号  
#define BUF_SIZE 1024        // 缓冲区大小  
  
int main() {    
    int sockfd; // 套接字文件描述符  
    struct sockaddr_in server_addr; // 服务器地址结构体  
    char message[BUF_SIZE] = {0}; // 用于存储要发送的消息的缓冲区  
  
    // 创建一个UDP套接字  
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {    
        perror("socket creation failed"); // 如果套接字创建失败,打印错误消息  
        return -1; // 返回-1表示程序异常退出  
    }    
  
    // 初始化服务器地址结构体  
    memset(&server_addr, 0, sizeof(server_addr)); // 将结构体内容全部设置为0  
    server_addr.sin_family = AF_INET; // 设置地址族为IPv4  
    server_addr.sin_port = htons(SERVER_PORT); // 端口号需要转换为网络字节序  
    socklen_t server_len = sizeof(server_addr); // 定义一个socklen_t类型的变量,用于存储地址结构体的长度  
  
    // 将点分十进制的IP地址转换为网络字节序的二进制形式  
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {    
        perror("invalid address/ Address not supported"); // 如果IP地址无效或不支持,打印错误消息  
        exit(EXIT_FAILURE); // 退出程序  
    }    
  
    // 发送数据到服务器  
    while(1){ // 无限循环,持续读取输入并发送  
        fgets(message, BUF_SIZE, stdin); // 从标准输入读取一行文本  
        ssize_t bytes_sent = sendto(sockfd, message, strlen(message), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr)); // 发送数据  
        if (bytes_sent == -1) {    
            perror("sendto failed"); // 如果发送失败,打印错误消息  
            return -1; // 返回-1表示程序异常退出  
        }  
  
        // 注意:这里尝试从同一个地址接收数据可能不是UDP的典型用法  
        // 因为UDP是无连接的,接收的数据可能来自任何源  
        recvfrom(sockfd, message, BUF_SIZE, 0, (struct sockaddr *)&server_addr, &server_len); // 尝试接收数据  
  
        // 注意:这里没有处理接收到的数据,通常你会想要检查recvfrom的返回值并处理接收到的数据  
  
        // 由于UDP是无连接的,你可能想要使用另一个变量来保存接收地址,或者只是忽略接收地址并处理数据  
    }  
  
    // 注意:由于上面的while循环是无限循环,所以下面的代码永远不会被执行  
    //printf("Sent %zd bytes\n", bytes_sent);    
  
    // 关闭套接字(但上面的代码永远不会到达这里)  
    close(sockfd);    
  
    return 0; // 程序正常退出(但上面的代码永远不会到达这里)  
}
注意:

SERVER_IP 设置为 "0.0.0.0" 是不合适的,因为 "0.0.0.0" 通常用于服务器监听所有网络接口。作为客户端,你应该指定一个具体的服务器IP地址。
UDP是无连接的,所以尝试从同一个地址接收数据可能不是UDP的典型用法。你可能想要接收来自任何源的数据,并相应地处理它们。
上面的 recvfrom 调用没有处理接收到的数据。在实际应用中,你应该检查 recvfrom 的返回值,并处理接收到的数据。
4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/610886.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动化中遇到的问题归纳总结

1、动态元素定位不到 解决方法&#xff1a;尽量使用固定元素定位&#xff0c;如没有固定元素&#xff0c;则采用绝对路径进行定位&#xff0c;因为元素路径是唯一且不变的 2、自动化脚本执行速度较慢 尽量使用css方法定位元素&#xff0c;使用等待时&#xff0c;少用sleep方…

【双碳系列】碳中和、碳排放、温室气体、弹手指、碳储量、碳循环及leap、cge、dice、openLCA模型

气候变化是当前人类生存和发展所面临的共同挑战&#xff0c;受到世界各国人民和政府的高度关注 ①“双碳”目标下资源环境中的可计算一般均衡&#xff08;CGE&#xff09;模型实践技术应用 可计算一般均衡模型&#xff08;CGE模型&#xff09;由于其能够模拟宏观经济系统运行…

【机器学习】逻辑化讲清PCA主成分分析

碎碎念&#xff1a;小编去年数学建模比赛的时候真的理解不了主成分分析中的“主成分”的概念&#xff01;&#xff01;但是&#xff0c;时隔两年&#xff0c;在机器学习领域我又行了&#xff0c;终于搞明白了&#xff01;且看正文&#xff01;再分享一个今天听到的播客中非常触…

【网络安全入门】新手如何参加护网行动?一篇带你零基础入门到精通

前言 “没有网络安全就没有国家安全”。 当前&#xff0c;网络安全已被提升到国家战略的高度&#xff0c;成为影响国家安全、社会稳定至关重要的因素之一。 一、网络安全行业特点 行业发展空间大&#xff0c;岗位非常多 网络安全行业产业以来&#xff0c;随即新增加了几十个…

LaTeX公式学习笔记

\sqrt[3]{100} \frac{2}{3} \sum_{i0}^{n} x^{3} \log_{a}{b} \vec{a} \bar{a} \lim_{x \to \infty} \Delta A B C

自动驾驶系统中的端到端学习

资料下载-《自动驾驶系统中的端到端学习&#xff08;2020&#xff09;》https://mp.weixin.qq.com/s/ttNpsn7qyVWvDMZzluU_pA 近年来&#xff0c;卷积神经网络显著提高了视觉感知能力。实现这一成功的两个主要因素是将简单的模块组合成复杂的网络和端到端的优化。然而&#xf…

哪里有高清视频素材软件?哪里有视频素材网站?

在这个视觉内容至关重要的时代&#xff0c;高质量的视频素材不仅能够增强信息传递的效果&#xff0c;还能显著提升观众的观看体验。接下来介绍的这些视频素材网站&#xff0c;将为您的创作提供广泛的选择&#xff0c;从本土到国际&#xff0c;满足您不同的需求和偏好。 1. 蛙学…

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2 1、 for i in range(3):Dev.step(3)Dev.turnRight()Dev.step(4)Dev.turnLeft()2、 for i in range(3):Spaceship.step(3)Spaceship.turnRight()Spaceship.step(1)3、 Dev.turnLeft() Dev.step(Dev.x - Item[1].…

CrossManager软件安装

目录 一、CrossManager软件 1.1 下载安装程序&#xff1a; 1.2 注册-登录 1.3 运行安装程序 1.4 完成安装&#xff1a; 1.5 激活软件&#xff1a; 文章底部可获取安装包---CrossManager软件安装&#xff08;有效期30天&#xff09; 当涉及到专业的软件安装和配置时&…

Java Web 学习笔记(一) —— MySQL(3)

目录 1 Mysql 函数1.1 日期函数1.2 判断函数1.3 字符函数1.4 数学函数 2 Mysql 性能2.1 提高操作数据库性能2.2 执行次数比较多的语句2.3 sql语句的执行效率 3 Mysql 优化&#xff08;***&#xff09;3.1 定位慢查询3.2 SQL执行计划3.3 索引3.3.1 索引介绍与分类3.3.2 索引的使…

Python 3 中zip()函数的用法

1 创作灵感 我们在阅读代码的时候&#xff0c;经常会看到zip函数&#xff0c;有的时候还和循环在一起用&#xff0c;今天举几个例子测试一下该函数的用法 2.应用举例 &#xff08;1&#xff09;定义了两个列表一个是num,一个是letter (2)使用zip可以把num列表和letter列表中…

大模型微调之 在亚马逊AWS上实战LlaMA案例(七)

大模型微调之 在亚马逊AWS上实战LlaMA案例&#xff08;七&#xff09; 微调SageMaker JumpStart上的LLaMA 2模型 这是在us-west-2的测试结果。 展示了如何使用SageMaker Python SDK部署预训练的Llama 2模型&#xff0c;并将其微调到你的数据集&#xff0c;用于领域适应或指令…

numpy1

注意&#xff1a;reshape函数的 - 1&#xff08;是让电脑 自己计算的意思 import numpy as np n np.arange(0,25).reshape(5,5) m np.array([0,5,10,15,20])nn np.repeat(n,2,axis 1) m m.reshape(-1,1)nn[:,1:8:2] np.tile(m,(1,4)) nn[:,0:-1]

无人机+光电吊舱:四光(可见光+红外热成像+广角+激光测距)吊舱设计技术详解

无人机与光电吊舱的结合&#xff0c;特别是四光吊舱&#xff08;包含可见光、红外热成像、广角和激光测距技术&#xff09;的应用&#xff0c;为无人机提供了强大的侦察和测量能力。以下是对四光吊舱设计技术的详解&#xff1a; 1. 可见光技术&#xff1a;可见光相机是吊舱中最…

螺栓扭矩如何设计?——SunTorque智能扭矩系统

螺栓扭矩设计的大小是一个涉及工程实践的重要问题&#xff0c;它直接关系到螺栓连接的紧固质量和安全性。螺栓扭矩是工程领域中常用的一个概念&#xff0c;用来描述螺栓在连接过程中所需的旋转力矩。正确的螺栓扭矩可以确保螺栓和螺母之间的紧密连接&#xff0c;避免由于松动而…

Java入门基础学习笔记10——变量

变量的学习路径&#xff1a; 认识变量->为什么要用变量&#xff1f;->变量有啥特点&#xff1f;->变量有啥应用场景&#xff1f; 什么是变量&#xff1f; 变量是用来记住程序要处理的数据的。 变量的定义格式&#xff1a; 数据类型 变量名称 数据&#xff1b; 数…

C语言/数据结构——(用双链表实现数据的增删查改)

一.前言 嗨嗨嗨&#xff0c;大家好久不见&#xff01;前面我们已经通过数组实现数据的增删查改、单链表实现数据的增删查改&#xff0c;现在让我们尝试一下使用双链表实现数据的增删查改吧&#xff01; 二.正文 如同往常一样&#xff0c;对于稍微大点的项目来说&#xff0c;…

2024洗地机选购指南 | 怎么选洗地机不会被坑?

家里的地板总是需要打扫&#xff0c;但工作忙碌的我们往往没有足够的时间来打理。洗地机不仅能够帮助我们节省宝贵的时间&#xff0c;还能让我们的家变得一尘不染。今天&#xff0c;笔者将为大家讲讲挑选洗地机的技巧&#xff0c;告诉大家怎么挑选洗地机不会被坑&#xff0c;顺…

解锁楼宇自动化新维度西门子Insight+BACnet IP I/O控制器

数字城市的楼宇自动化已不再是一个遥不可及的概念&#xff0c;而是成为了现代建筑的标配。特别是在大型商业综合体、高端写字楼和公共设施中&#xff0c;高效的楼宇管理系统是确保环境舒适度与能源效率的关键。当提及楼宇自动化领域的佼佼者&#xff0c;西门子Insight楼宇自动化…

【洛谷】动态规划之最长公共子序列

前言&#xff1a; 本系列目的是记录日常所刷的题&#xff0c;有的是自己想出来的题&#xff0c;有的是看了大佬题解后想明白的题 题目 P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 前提&#xff1a; 两个排列都是1到n的排列&#xff0c;说…
最新文章