当前位置: 首页 > news >正文

网络编程:UDP编程笔记

1.字节序的概念和转换

小端格式: 低位字节数据存储在低地址
大端格式: 高位字节数据存储在低地址
在这里插入图片描述
在主机上时为小端存储,在网络上时为大端,所以接收到数据时,要转为小端口
如下图:
在这里插入图片描述
#include <arpa/inet.h>
发送者调用的函数:
uint32_t htonl(uint32_t hostlong); //转ip 将32位的主机字节序转换为 网络字符节
uint16_t htons(uint16_t hostshort); //转端口 将16位的主机字节序转换为 网络字符节

接收者者调用的函数:
uint32_t ntohl(uint32_t netlong); //转ip 将32位的网络字节序转换为 主机字符节
uint16_t ntohs(uint16_t netshort); //转端口 将16位的网络字节序转换为 主机字符节

2.IP地址转换

#include <arpa/inet.h>
点分十进制 转为 32位无符号整数
转换函数:
**int inet_pton(int af , const char src , void dst);
参数:
af : 转换的协议
AF_INET (IPv4)
AF_INET6 (IPv6)
src : 点分十进制数串的首元素地址
dst : 4字节的IP地址
返回值: 成功 1 失败 -1

32位无符号整数 转为 点分十进制
**const char *inet_ntop(int af , const void src , char dst, socklen_t size);
参数:
af : 转换的协议, 如 AF_INET (IPv4) AF_INET6 (IPv6)
src :4字节的IP地址的起始地址
dst :存放点分十进制数串的起始地址
size:点分十进制数串的最大长度
#define INET_ADDRSTRLEN 16 //for ipv4
#define INET6_ADDRSTRLEN 46 //for ipv6
返回值: 成功则返回字符串的首地址; 失败则返回NULL

UDP编程

发送方:

  // 创建socket
// 创建 地址结构体 sockaddr_in   
// 准备 数据
// 发送 sendto()

ssize_t sendto(int sockfd,const void * buf,size_t nbytes, int flags,const struct sockaddr *to, socklen_t addrlen)

参数:
sockfd:套接字
buf: 发送数据缓冲区
nbytes: 发送数据缓冲区的大小
flags:一般为 0
to:指向目的主机地址结构体的指针
addrlen:to 所指向内容的长度

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main(){int sock_fd = socket(AF_INET,SOCK_DGRAM,0); // 创建socket// 创建 地址结构体 sockaddr_in  struct sockaddr_in dstaddr;dstaddr.sin_family=AF_INET;dstaddr.sin_addr.s_addr =inet_addr("192.168.74.1");dstaddr.sin_port = htons(8000);//数据char data[]="helloudp\n";//将sockaddr_in 转换为sockaddr  发送数据 sendto()ssize_t len =sendto(sock_fd,data,sizeof(data),0,(struct sockaddr *)&dstaddr,sizeof(dstaddr));close(sock_fd);return 0;
}
接收方:
  // 创建socket
// 创建 地址结构体 sockaddr_in   // 让定义的套接字固定绑定  IP 和 portwhile(1){
// 准备 数据
// 接收 recvfrom ()
}
**ssize_t recvfrom(int sockfd,void \*buf, size_t nbytes,int flags,struct sockaddr \*from,socklen_t \*addrlen);**

参数:
sockfd: 套接字
buf:接收数据缓冲区
nbytes: 接收数据缓冲区的大小
flags: 套接字标志(常为 0)
from: 源地址结构体指针,用来保存数据的来源
addrlen: from 所指内容的长度
注意:通过 from 和 addrlen 参数存放数据来源信息 ,from 和 addrlen 可以为 NULL, 表示不保存数据来源。

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
int main(){//定义一个套接字;int sfd=socket(AF_INET,SOCK_DGRAM,0);//定义IPv4 的地址结构;struct sockaddr_in localaddr;localaddr.sin_family=AF_INET; //指明 IPv4localaddr.sin_port=htons(8000);//指明端口号,转换为大端口;  ???localaddr.sin_addr.s_addr =htonl(INADDR_ANY);//表示任意的本地IP地址,转换为//让定义的套接字固定绑定  IP 和 portbind(sfd,(struct sockaddr *)&localaddr,sizeof(localaddr));//持续监听-----while(1){char buf[128];struct sockaddr_in fromaddr;  //存储 发送者的地址和端口socklen_t slen;//接收数据ssize_t len = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&fromaddr,&slen);if(len>0){buf[len]=0;//接收到数据char ip[INET_ADDRSTRLEN];//发送方的IP 转换为点分十进制,同时自动转换为小端口格式inet_ntop(AF_INET,&fromaddr.sin_addr.s_addr,ip,INET_ADDRSTRLEN);uint16_t port =ntohs(fromaddr.sin_port);//将发送方的端口转换为小格式printf("%s:%d->%s\n",ip,port,buf);if(strncmp(buf,"bye",3)==0) break;}}close(sfd);return 0;
}

相关文章:

  • (一)Docker基本介绍
  • 【PYG】dataloader和densedataloader
  • 解决Linux环境Qt报“cannot find -lgl“问题
  • 2024.7.5
  • 【单链表】04 试编写算法将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为0(1)。
  • VPN是什么?
  • 实验三 图像增强—灰度变换
  • Windows 11 安装 安卓子系统 (WSA)
  • Cesium与Three相机同步(3)
  • 安装局部的typeScript环境
  • 【C++】 解决 C++ 语言报错:Undefined Reference
  • window上部署sql server改动端口、和sqlserver的一些还原、批量插入存储过程的命令
  • Django 模版继承
  • Linux Shell 脚本入门教程:开启你的自动化之旅
  • Python使用(...)连接字符串
  • angular2开源库收集
  • Javascript弹出层-初探
  • Java精华积累:初学者都应该搞懂的问题
  • Js基础知识(一) - 变量
  • Laravel5.4 Queues队列学习
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • webgl (原生)基础入门指南【一】
  • 工作中总结前端开发流程--vue项目
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用API自动生成工具优化前端工作流
  • 小而合理的前端理论:rscss和rsjs
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​​​​​​​​​​​​​​Γ函数
  • #define,static,const,三种常量的区别
  • #QT项目实战(天气预报)
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (void) (_x == _y)的作用
  • (搬运以学习)flask 上下文的实现
  • (多级缓存)多级缓存
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (三) diretfbrc详解
  • (三)elasticsearch 源码之启动流程分析
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (一)SvelteKit教程:hello world
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .net FrameWork简介,数组,枚举
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .sh
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @RequestParam详解
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [codevs] 1029 遍历问题