基于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.mzph.cn/diannao/11694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年3月 青少年等级考试机器人理论真题二级

202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车&#xff0c;用左右两个电机分别控制左右车轮&#xff0c;左侧电机转速是100rpm&#xff0c;右侧电机转速是50rpm&#xff0c;则此机器小车&#xff1f;&#xff08; &#xff09; A&#xff1a;原地右转 B&am…

华企盾DSC数据防泄密软件有哪些水印功能?

在企业数据安全领域&#xff0c;水印技术是一种重要的信息保护策略&#xff0c;用于防止数据泄露和确保信息的原始性和完整性。根据回顾的资料&#xff0c;以下是企业中常用的几种水印技术&#xff1a; 屏幕浮水印&#xff1a;这种水印能够在用户的屏幕上显示公司的标志或者其他…

Golang SDK安装

windows环境安装 1.链接: 下载地址 2.安装SDK 检查环境变量&#xff1a; 3.开启go modules,命令行执行一下命令&#xff1a; go env -w GO111MODULEon4.设置国内代理&#xff0c;命令行执行一下命令&#xff1a; go env -w GOPROXYhttps://proxy.golang.com.cn,https:/…

C#之partial关键字

在C#中&#xff0c;partial关键字用于声明一个类、结构体、接口或方法的分部定义。这意味着可以将一个类或其他类型的定义分成多个部分&#xff0c;这些部分可以在同一个命名空间或程序集中的多个源文件中进行定义。当编译器编译这些部分时&#xff0c;会将它们合并成一个单独的…

打印机 ansible配置dhcp和打印机

部署dhcp服务器 主机发送Discover报文 目标为广播地址 同一网段的dhcp收到报文后&#xff0c;dhcp响应一个offer报文 offer报文&#xff1a;dhcp自己的ip地址。和客户端ip以及使用周期&#xff0c;和客户端ip网络参数 最后主机单独发一个request报文 给那个选择的dhcp服务器 &…

JUC下的ThreadLocalRandom详解

ThreadLocalRandom 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个随机数生成器类&#xff0c;它是从Java 7开始引入的。相较于传统的Math.random()或Random类&#xff0c;ThreadLocalRandom更适用于多线程环境&#xff0c;因为它为每个线程维护了一个…

福建医疗器械展/2024厦门国际医疗器械展览会重磅来袭

2024中国&#xff08;厦门&#xff09;国际医疗器械展览会 时 间&#xff1a;2024年11月1-3日 November 1-3, 2024 地 点&#xff1a;厦门国际会展中心 Xiamen International Conference & Exhibition Center ​ ◆组织机构 主办单位&#xff1a; 中国技术市场协会医…

Blazor入门-调用js+例子

参考&#xff1a; Blazor入门笔记&#xff08;3&#xff09;-C#与JS交互 - 半野 - 博客园 https://www.cnblogs.com/zxyao/p/12638233.html Blazor项目如何调用js文件_blazor加载js-CSDN博客 https://blog.csdn.net/bdbox/article/details/135438411 本地环境&#xff1a;win1…

六西格玛绿带培训:企业变革的催化剂,个人成长的助推器!

六西格玛绿带培训不仅是一套系统的管理方法&#xff0c;更是一种追求卓越、持续改进的文化和思维方式。它强调以数据为基础&#xff0c;通过科学的分析和决策&#xff0c;实现质量的飞跃和成本的优化。对于企业来说&#xff0c;六西格玛绿带培训能够帮助企业建立可靠的质量管理…

Spring STOMP-消息代理

简单的消息代理 内置的简单消息代理会处理来自客户端的订阅请求&#xff0c;将请求消息存储在内存中&#xff0c;并广播消息给匹配destination的连接客户端。代理支持路径式destination&#xff0c;包括订阅Ant风格的destinations模式。 应用程序也可以使用点分隔&#xff08;…

【车辆安全管理】风险预测

近期又发生了很多车辆事故&#xff0c; https://news.sina.com.cn/s/2024-05-13/doc-inavapur2236074.shtml 其实都是可以避免的&#xff0c;如果车辆有很好的自动减速系统&#xff0c;如特斯拉的FSD系统&#xff0c; 特斯拉的FSD&#xff08;Full-Self Driving&#xff09;…

11、24年--信息技术发展——新一代信息技术及应用

1、物联网 物联网(The Internet of Things)是指通过信息传感设备,按约定的协议将任何物品与互联网相连接,进行信息交换和通信,以实现智能化识别、定位、跟踪、监控和管理的网络。 1.1 技术基础 物联网架构可分为三层:感知层、网络层和应用层。感知层由各种传感器…

AI翻唱+视频剪辑全流程实战

目录 一、AI翻唱之模型训练 &#xff08;1&#xff09;模型部署 &#xff08;2&#xff09;数据集制作——搜集素材 &#xff08;3&#xff09;数据集制作——提升音频质量 方法一&#xff1a;使用RVC提供的音频处理功能。 方法二&#xff1a;可以使用音频剪辑工具Ad…

我是如何免费抵御一个多月的 DDos/CC 攻击的?

今天明月给大家详细分享一下我的博客是如何免费抵御了长达一个多月的 DDos/CC 攻击的&#xff0c;在【现在 DDos/CC 攻击门槛低的可怕&#xff01;】一文里明月就说过现在 DDos/CC 攻击几乎是没有门槛的&#xff0c;任何一个老鼠屎在群里看到你的博客都可以轻松便捷的发动一次 …

R语言数据分析案例-股票题目分析

Value at Risk&#xff08;VaR&#xff09;是一种统计技术&#xff0c;用于量化投资组合在正常市场条件下可能遭受的最大潜在损失。它是风险管理和金融领域中一个非常重要的概念。VaR通常以货币单位表示&#xff0c;用于估计在给定的置信水平和特定时间范围内&#xff0c;投资组…

宝塔助手v1.4.1/手机操控云服务器的神器软件

宝塔助手是以宝塔Linux面板提供的API开发的一款可以随时随地管理服务器的APP。通过这款APP你可以随时随地的查看一台或多台服务器的运行情况&#xff0c;对服务器网站、FTP、数据库、文件进行管理。内置文件编辑器&#xff0c;可以对网站文件进行修改。 链接&#xff1a;https:…

Java PowerMockito static方法/new对象/public方法/private方法/public属性/private属性

Java PowerMockito static方法/new对象/public方法/private方法/public属性/private属性 1 变量Mock1.1 公有变量1.2 私有变量1.3 公有静态变量1.4 私有静态变量 2 方法Mock2.1 共有方法2.2 私有方法2.3 共有静态方法2.4 共有最终方法 3 new对象Mock3.1 共有方法 1 变量Mock p…

【ARM Cortex-M 系列 2.2 -- Cortex-M7 单步调试原理及实现详细介绍】

请阅读【嵌入式开发学习必备专栏】 文章目录 单步调试概述单步执行原理Debug stepping control using the DHCSR 紧接上篇文章 【ARM Cortex-M 系列 2.1 – Cortex-M7 Debug system registers】 单步调试概述 在ARMv7-M架构中&#xff0c;通过使用单步调试&#xff08;Haltin…

数据结构与算法学习笔记一---顺序表的静态存储表示和实现(C语言)

目录 1.顺序表的静态存储过程 1.初始化 2.销毁 3.清空 4.表长 5.获取数据元素 6.直接前驱 7.直接后继 8.插入 9.删除 10.遍历 11.测试代码 前言 这篇博客主要是顺序表的静态分配存储表示。 1.顺序表的静态存储过程 我们使用静态数据来存储顺序表中的数据元素&#…

粒子群算法(Particle Swarm Optimization)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;的灵感来源于鸟群或鱼群的觅食行为。想象一下&a…