【网络编程】第二天 UDP编程
目录一、字节序二、网络字节序和主机字节序三、 字节序的转换函数四、地址转换函数五、UDP编程概述1、socket2、udp的编程流程​3、socket函数创建一个套接字通信的端点4、IPv4地址结构体5、通用套接字地址结构6、sendto发送udp消息7、bind给套接字绑定固定的IP和端口8、recvfrom接收数据阻塞一、字节序将多字节看成一个整体存储的顺序。 文件——字节流流指针字节序分为大端格式、小端格式。大小端是系统决定的不能自由更改。判断当前系统是大端还是小端只需要判断低地址 存放的是高字节 还是低字节二、网络字节序和主机字节序如果计算机没有考虑字节序的问题导致传输的数据错误 解决上述问题:网络中的数据 必须是大端。发送数据需要将 主机字节序 转 网络字节序hton接收数据需要将 网络字节序 转 主机字节序ntoh三、 字节序的转换函数头文件#include arpa/inet.h1、主机字节序 转 网络字节序发送数据uint32_t htonl(uint32_t hostint32);//转IPuint16_t htons(uint16_t hostint16);//转端口号2、网络字节序 转 主机字节序接收数据uint32_t ntohl(uint32_t netint32);//转IPuint16_t ntohs(uint16_t netint16);//转端口四、地址转换函数10.9.11.3 点分十进制数串 用户识别的IP地址计算机 是用32位无符号数据 存储IP地址 。发送数据 将点分十进制数据 转换成 32为无符号数据 #include arpa/inet.hint inet_pton(int family,const char *strptr, void *addrptr);功能 将点分十进制数串转换成32位无符号整数参数family 协议族 AF_INET‐‐IPv4 AF_INET6‐‐IPv6strptr 点分十进制数串addrptr 32位无符号整数的地址返回值 成功返回1 、 失败返回其它接收数据 将32为无符号数据 转换成 点分十进制数串const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len)功能 将32位无符号整数转换成点分十进制数串参数family 协议族 AF_INETaddrptr 32位无符号整数strptr 点分十进制数串len strptr缓存区长度len的宏定义#define INET_ADDRSTRLEN 16 //for ipv4#define INET6_ADDRSTRLEN 46 //for ipv6返回值 成功:则返回字符串的首地址 失败:返回NULL五、UDP编程概述1、socket网络通信的3要素IP、PORT、协议socket 他是网络编程接口的统称。socket 他是通信的一个端点IP、PORT信息也是特殊的文件描述符套接字。2、udp的编程流程3、socket函数创建一个套接字通信的端点#include sys/socket.hint socket(int family,int type,int protocol);功能 创建一个用于网络通信的socket套接字描述符参数family:协议族(AF_INET、AF_INET6、PF_PACKET(链路层编程接口等)type:套接字类(SOCK_STREAMTCP、SOCK_DGRAMUDP、SOCK_RAW等)protocol:协议类别(0、IPPROTO_TCP、IPPROTO_UDP等返回值 套接字特点 创建套接字时系统不会分配端口4、IPv4地址结构体定义 地址结构体变量#include netinet/in.h struct in_addr { in_addr_t s_addr;//4字节 }; struct sockaddr_in //IPv4地址结构体 { sa_family_t sin_family;//2字节 AF_INET AF_INET6 in_port_t sin_port;//2字节 struct in_addr sin_addr;//4字节 char sin_zero[8]//8字节 };5、通用套接字地址结构对传递给函数的实参进行类型转换不做赋值操作struct sockaddr { sa_family_t sa_family; // 2字节 char sa_data[14] //14字节 };6、sendto发送udp消息ssize_t sendto(int sockfdconst void *buf,size_t nbytes,int flags,const struct sockaddr *to, socklen_t addrlen);功能 向to结构体指针中指定的ip发送UDP数据参数sockfd套接字buf 发送数据缓冲区nbytes: 发送数据缓冲区的大小flags一般为0to 指向目的主机地址结构体的指针addrlento所指向内容的长度注意通过to和addrlen确定目的地址可以发送0长度的UDP数据包返回值 成功:发送数据的字符数 失败: ‐1例1发送消息#include stdio.h #include sys/socket.h // socket #include unistd.h // close #include string.h // memset strlen #include netinet/in.h // struct sockaddr_in #include arpa/inet.h // inet_pton int main(int argc, char const *argv[]) { // 创建用于通信的udp套接字 int sockfd socket(AF_INET, SOCK_DGRAM, 0); if (sockfd 0) { perror(socket); return 0; } printf(sockfd %d\n, sockfd); // 发送数据 sendto char buf[] hello sockfd; // 目的地址信息 struct sockaddr_in dst_addr; memset(dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family AF_INET; // IPv4 dst_addr.sin_port htons(8080); // 端口 // 将目的IP 赋值到地址结构体中 inet_pton(AF_INET, 10.9.11.251, dst_addr.sin_addr.s_addr); // 如果套接字 没有事先bind绑定固定的IP以及端口 // 那么第一次调用sendto的时候系统会给本地主机IP,以及随机端口作为源地址信息 sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)dst_addr, sizeof(dst_addr)); char buf1[] hello buf1; sendto(sockfd, buf1, strlen(buf1), 0, (struct sockaddr *)dst_addr, sizeof(dst_addr)); close(sockfd); return 0; }7、bind给套接字绑定固定的IP和端口bind只能绑定本地机的IP地址创建套接字bind固定IP以及端口sendto发送数据或recvfrom接收数据int bind(int sockfd,const struct sockaddr *myaddrsocklen_t addrlen);功能 将本地协议地址与sockfd绑定参数sockfd socket套接字myaddr 指向特定协议的地址结构指针addrlen该地址结构的长度返回值 成功返回0 失败其他#include stdio.h #include sys/socket.h // socket #include unistd.h // close #include string.h // memset strlen #include netinet/in.h // struct sockaddr_in #include arpa/inet.h // inet_pton int main(int argc, char const *argv[]) { // 创建用于通信的udp套接字 int sockfd socket(AF_INET, SOCK_DGRAM, 0); if (sockfd 0) { perror(socket); return 0; } printf(sockfd %d\n, sockfd); // bind固定的IP以及端口 struct sockaddr_in my_addr; memset(my_addr, 0, sizeof(my_addr)); my_addr.sin_family AF_INET; my_addr.sin_port htons(9000); // 源端口 my_addr.sin_addr.s_addr htonl(INADDR_ANY); // 通配地址 int ret bind(sockfd, (struct sockaddr *)my_addr, sizeof(my_addr)); if (ret 0) { // Handle error } { perror(bind); return 0; } // 发送数据 sendto char buf[] hello sockfd; // 目的地址信息 struct sockaddr_in dst_addr; memset(dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family AF_INET; // IPv4 dst_addr.sin_port htons(8080); // 端口 // 将目的IP 赋值到地址结构体中 inet_pton(AF_INET, 100.92.78.145, dst_addr.sin_addr.s_addr); // 如果套接字 没有事先bind绑定固定的IP以及端口 // 那么第一次调用sendto的时候系统会给本地主机IP,以及随机端口作为源地址信息 sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)dst_addr, sizeof(dst_addr)); char buf1[] hello buf1; sendto(sockfd, buf1, strlen(buf1), 0, (struct sockaddr *)dst_addr, sizeof(dst_addr)); close(sockfd); return 0; }8、recvfrom接收数据阻塞先bind固定的端口以及IPssize_t recvfrom(int sockfd, void *buf,size_t nbytes,int flags, struct sockaddr *from,socklen_t *addrlen);功能 接收UDP数据并将源地址信息保存在from指向的结构中参数sockfd: 套接字buf接收数据缓冲区nbytes:接收数据缓冲区的大小flags 套接字标志(常为0)from 源地址结构体指针用来保存数据的来源addrlen: from所指内容的长度注意通过from和addrlen参数存放数据来源信息from和addrlen可以为NULL, 表示不保存数据来源返回值 成功:接收到的字符数 失败: ‐1#include stdio.h #include sys/socket.h // socket #include unistd.h // close #include string.h // memset strlen #include netinet/in.h // struct sockaddr_in #include arpa/inet.h // inet_pton int main(int argc, char const *argv[]) { // 创建用于通信的udp套接字 int sockfd socket(AF_INET, SOCK_DGRAM, 0); if (sockfd 0) { perror(socket); return 0; } printf(sockfd %d\n, sockfd); // bind固定的IP以及端口 struct sockaddr_in my_addr; memset(my_addr, 0, sizeof(my_addr)); my_addr.sin_family AF_INET; my_addr.sin_port htons(8000); // 源端口 my_addr.sin_addr.s_addr htonl(INADDR_ANY); // 通配地址 int ret bind(sockfd, (struct sockaddr *)my_addr, sizeof(my_addr)); if (ret 0) { perror(bind); return 0; } // recvfrom接收数据 while (1) { unsigned char buf[1500] ; struct sockaddr_in from_addr; socklen_t from_len sizeof(from_addr); // from_addr, from_len可传NULL表示不关心对方的ip int len recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)from_addr, from_len); if (len 0) { perror(recvfrom); return 0; } // 获取发送者的IP char ip_str[16] ; inet_ntop(AF_INET, from_addr.sin_addr.s_addr, ip_str, 16); // 获取发送者的端口 unsigned short port ntohs(from_addr.sin_port); printf(IP:%s PORT:%hu 长度%d 消息:%s\n, ip_str, port, len, buf); } close(sockfd); return 0; }#include stdio.h #include sys/socket.h // socket #include unistd.h // close #include string.h // memset strlen #include netinet/in.h // struct sockaddr_in #include arpa/inet.h // inet_pton #include pthread.h #include stdlib.h //htons void *send_fun(void *arg) { struct sockaddr_in dst_addr; memset(dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family AF_INET; int sockfd *(int *)arg; while (1) { char buf[128] ; fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] 0; if (strncmp(buf, sayto, 5) 0) { char ip_str[16] ; unsigned short port 0; sscanf(buf, sayto %s %hu, ip_str, port); dst_addr.sin_port htons(port); inet_pton(AF_INET, ip_str, dst_addr.sin_addr.s_addr); continue; } else if (strncmp(buf, quit, 4) 0) { return NULL; } sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)dst_addr, sizeof(dst_addr)); } return NULL; } void *recv_fun(void *arg) { int sockfd *(int *)arg; while (1) { unsigned char buf[1500] ; struct sockaddr_in from_addr; socklen_t from_len sizeof(from_addr); int len recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)from_addr, from_len); if (len 0) { perror(recvfrom); return 0; } char ip_str[16] ; inet_ntop(AF_INET, from_addr.sin_addr.s_addr, ip_str, 16); unsigned short port ntohs(from_addr.sin_port); printf(IP:%s PORT:%hu 长度%d 消息:%s\n, ip_str, port, len, buf); } } int main(int argc, char const *argv[]) { if (argc ! 2) { printf(./a.out 8000\n); return 0; } int sockfd socket(AF_INET, SOCK_DGRAM, 0); if (sockfd 0) { perror(socket); return 0; } printf(sockfd %d\n, sockfd); struct sockaddr_in my_addr; memset(my_addr, 0, sizeof(my_addr)); my_addr.sin_family AF_INET; my_addr.sin_port htons(atoi(argv[1])); // 源端口 my_addr.sin_addr.s_addr htonl(INADDR_ANY); // 通配地址 int ret bind(sockfd, (struct sockaddr *)my_addr, sizeof(my_addr)); if (ret 0) { perror(bind); return 0; } pthread_t tid1, tid2; pthread_create(tid1, NULL, send_fun, (void *)sockfd); pthread_create(tid2, NULL, recv_fun, (void *)sockfd); pthread_join(tid1, NULL); pthread_cancel(tid2); pthread_join(tid2, NULL); close(sockfd); return 0; }

相关新闻

实战指南:如何高效配置智能自动化工具解放《崩坏:星穹铁道》模拟宇宙

实战指南:如何高效配置智能自动化工具解放《崩坏:星穹铁道》模拟宇宙

实战指南:如何高效配置智能自动化工具解放《崩坏:星穹铁道》模拟宇宙 【免费下载链接】Auto_Simulated_Universe 崩坏:星穹铁道 模拟宇宙自动化 (Honkai Star Rail - Auto Simulated Universe) 项目地址: https://gi…

2026/10/13 8:41:43 阅读更多 →
AI白底图不是“一键”,而是“一链”:从光照模拟→阴影重建→色域映射→平台适配的8节点工业级Pipeline(含Docker部署脚本)

AI白底图不是“一键”,而是“一链”:从光照模拟→阴影重建→色域映射→平台适配的8节点工业级Pipeline(含Docker部署脚本)

更多请点击: https://codechina.net 第一章:AI图片 产品白底图 在电商与数字营销场景中,高质量的产品白底图是提升转化率的关键视觉资产。传统人工抠图背景替换流程耗时长、成本高,而基于AI的自动化白底图生成技术已实现端到端交…

2026/10/2 5:41:56 阅读更多 →
TMS320C80 MVP多任务内核设计:消息传递与异构计算协同机制解析

TMS320C80 MVP多任务内核设计:消息传递与异构计算协同机制解析

1. 项目概述:TMS320C80 MVP多任务内核的设计哲学与核心价值在90年代中期,德州仪器(TI)推出的TMS320C80 MVP(Multimedia Video Processor)是一款划时代的单芯片多处理器DSP设备。它集成了一个32位RISC架构的…

2026/10/5 9:16:10 阅读更多 →

最新新闻

Java面向对象编程与泛型实战解析

Java面向对象编程与泛型实战解析

1. 面向对象编程核心概念解析面向对象编程(OOP)是Java语言的基石,理解其核心概念对开发者至关重要。在实际项目开发中,我发现很多初级开发者虽然能背诵OOP的四大特性(封装、继承、多态、抽象),但…

2026/10/13 8:40:58 阅读更多 →
储能调峰配置与经济性分析:Matlab复现实战指南

储能调峰配置与经济性分析:Matlab复现实战指南

最近在做一个“参与调峰的储能系统配置方案及经济性分析”的EI复现项目,目标很明确:把一篇储能调峰领域的经济性优化文献,用Matlab从模型到仿真完整跑通。所谓EI复现,不是拿别人现成代码跑一遍那么简单,而是根据论文里…

2026/10/13 8:40:58 阅读更多 →
GaussDB(for PostgreSQL)入门实战:从建库建表到SQL操作与避坑指南

GaussDB(for PostgreSQL)入门实战:从建库建表到SQL操作与避坑指南

前一阵因为一个模拟项目X需要搭一套数据库环境,明确要求兼容PostgreSQL生态、能免去自建主从和高可用运维负担,我就把目标放在了某云厂商的GaussDB(for PostgreSQL)上。起初我以为这就是个“带分布式外衣的PG”,真正上手才发现,它…

2026/10/13 8:40:58 阅读更多 →
免费IP库实战:从数据清洗到本地查询服务搭建

免费IP库实战:从数据清洗到本地查询服务搭建

给日志分析系统加过IP归属地解析的兄弟,应该都懂这种体验:调在线接口查一次IP,速度快慢先不说,账单涨得比日志涨得还快。尤其流量稍大一些,按次计费的第三方接口根本经不起用。所以我一直觉得,“免费好用的…

2026/10/13 8:40:58 阅读更多 →
乒乓球拾球机器人机械结构设计:滚刷参数、电机选型与装配避坑全解

乒乓球拾球机器人机械结构设计:滚刷参数、电机选型与装配避坑全解

简介:这份PDF资料围绕自动拾取乒乓球机器人的机械结构设计展开,面向机器人工程、机械设计与自动化专业的师生及研究人员,聚焦乒乓球训练场景中捡球、送球环节的自动化需求。内容涵盖总体方案设计、轮式行走系统、微型真空泵捡球机构、平面四连…

2026/10/13 8:40:58 阅读更多 →
Agent技能拆解与编排实战:从碎片化到体系化

Agent技能拆解与编排实战:从碎片化到体系化

1. 技能碎片化:Agent落地的头号瓶颈这段时间在折腾智能体项目,我最大的体会就是:真正卡住进度的往往不是模型选型,不是推理框架,而是“技能”这层皮。模型再聪明,碰到实际任务时还是靠一个个具体技能去接活…

2026/10/13 8:39:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →