网络编程(字节序)

news2025/2/22 14:21:43

一、字节序的概念

字节序是指不同类型CPU主机,内存存储 多字节整数 序列的方式。

float, char, 字符串均没有字节序的说法

short, int , long , long long 有字节序的说法

小端字节序:低字节存储在低地址,高字节存储在高地址

大端字节序:低字节存储在高地址,高字节存储在低地址。

ps :

1. 取地址,获取的都是变量的首地址,即获取的是变量的最低的地址。

2. 内存中的数据读取,都是从低地址往高地址读取,读取完毕后经过大小端转换得到结果。

用共用体(联合体)的方式,判断本机的字节序?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
union
{
    unsigned int a;
    char b;
}s;
int main(int argc, const char *argv[])
{
    /*
       unsigned int a = 0x87654321;
       int* pa = &a;
       char b = 0;
       b = a;
       printf("%#x\n",*pa);
       printf("%#x\n",b);
       */
    /*
       unsigned int a =0x87654321;
       char *pa = (char*)&a;
       printf("%#x\n",*pa);
       if(0x21 == *pa)
       printf("这是一个小端字节序\n");
       else if(0x87 == *pa)
       printf("这是一个大端字节序\n");
       */
    s.a=0x87654321;
    printf("%#x\n",s.b);
    if(0x21 == s.b)
        printf("这是一个小端字节序\n");
    else if(0x87 == s.b)
        printf("这是一个大端字节序\n");

    return 0;
}
#include <stdio.h>

union t
{
    int a;
    char b;
};

int main(int argc, const char *argv[])
{
    unsigned int a = 0x87654321;
    char *pa = (char*)&a;

    if(0x21 == *pa)
        printf("这是一个小端\n");
    else if(0x87 == *pa)
        printf("这是一个大端\n");


    union t text;
    text.a = 1;                        
    if(1 == text.b)
        printf("这是一个小端\n");
    else if(0 == text.b)
        printf("这是一个大端\n");

    return 0;
}

 二、本地字节序与网络字节序

本地字节数:主机字节序(Host Byte Order) HBO

网络字节序(Network Byte Order) NBO,网络字节序规定使用大端字节序

在跨主机传输过程中,需要使用统一的字节序,即网络字节序,避免兼容性问题。

三、字节序转换函数

1)htons htonl 主机字节序-->网络字节序

头文件:

#include <arpa/inet.h>
​uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);

参数:指定要转换成网络字节序的整型:分别是32bit和16bit;

返回值:成功,返回转换后网络字节序的整型

#include <stdio.h>
#include <arpa/inet.h>
​
int main(int argc, const char *argv[])
{
    unsigned int a = 0x87654321;
    printf("%#x\n", a);             //0x87654321
    printf("%#x\n", htonl(a));      //0x21436587
​
    printf("%#x\n", htons(a));      //0x2143                 
    
    return 0;
}   

2)ntohs ntohl 网络字节序---->主机字节序

头文件:

#include <arpa/inet.h>

原型:

uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

参数:

uint32_t hostlong:32位网络字节序整型;
uint16_t hostshort:16位网络字节序整型;

返回值:成功,返回转换成主机字节序的整型;

四、结构体对齐

编译器会对结构体进行对齐,加速CPU取值周期,由于数据对齐也是与操作系统相关,不同的主机如果使用不同的对齐方式,会导致数据无法解析。

所以网络传输结构体的时候需要取消结构体对齐;

#include <stdio.h>
#pragma pack(1)         //设置默认对齐系数 :()中的参数只能填2^n (n=0,1,2,3,4,5......)  

typedef struct
{
    char a;     //1
    int b;      //4
    int d;      //4
}_A;
​
#pragma pack()      //重置默认对其系数,重新置为8
​
typedef struct
{
    char a;     //1
    int b;      //4
    int d;      //4
} __attribute__((packed))  B;       //取消结构体对齐
​
​
typedef struct
{   
    char a;     //1
                //3
    int b;      //4
    int d;      //4
}_C;
​
int main(int argc, const char *argv[])
{   
    printf("%ld\n", sizeof(_A));    //9
    printf("%ld\n", sizeof(_B));    //9
    printf("%ld\n", sizeof(_C));    //12
​
    
    return 0;
}

五、类型长度 

int long int不同操作系统这两个数据类型所占的字节数可能是不一样的

解决方式:可以通过通用类型:uint8_t uint16_t uint32_t

因为涉及到跨平台,不同平台会有不同的字长

#include <stdint.h>
​
typedef struct
{
    uint8_t a;      //1
    uint32_t b;      //4
    uint16_t d;      //2
}_A;

六、IP转换

由于IP地址本质上是一个4个字节的无符号整数,所以在跨主机传输中也有字节序的概念。

所以需要将IP地址转换成网络字节序。

"192.168.8.189" ---->本机字节序的整型 0xC0A808BD---->网络字节序0xBD08A8C0

"192.168.31.42"----> 0xC0A81F2A ---->0x2A1FA8C0

6.1点分十进制--->网络字节序

1)inet_aton

头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

原型:

int inet_aton(const char *cp, struct in_addr *inp);

参数:

char *cp:源IP地址的点分十进制字符串,例如 “192.168.1.10”;
struct in_addr *inp:存储转换成网络字节序的IP;
           typedef uint32_t in_addr_t;
           struct in_addr {
               in_addr_t s_addr;
           };

返回值:

成功,返回非0;
失败,返回0;
​只能转换IPv4

例子:

 #define IP  "192.168.1.10"      //0xC0A8010A
 int main(int argc, const char *argv[])
 {
     struct in_addr inp;
 
     if(inet_aton(IP, &inp) == 0)
     {
         printf("转换失败\n");
         return -1;
     }
 
     printf("%#X\n", inp.s_addr);    //0X0A01A8C0
                                                           
     return 0;
 }            

2)inet_pton(既可以转IPv4也能处理IPv6)

头文件:

#include <arpa/inet.h>

原型:

  int inet_pton(int af, const char *src, void *dst);

参数:

int af:协议族
            AF_INET         IPV4
            AF_INET6        IPV6
char *src:指定要转换成网络字节序的点分十进制字符串;
     void* dst
           typedef uint32_t in_addr_t;
           struct in_addr {
               in_addr_t s_addr;
           };
​
            af == AF_INETa;
            struct in6_addr
            {
            }

返回值:

成功,返回1;
失败,返回0或者-1,更新errno;

2)inet_addr 最常用

头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

原型:

uint32_t inet_addr(const char *cp);

参数:

char *cp:源IP地址的点分十进制字符串,例如 “192.168.1.10”;

返回值:

成功,返回转换后的网络字节序IP地址;
typedef uint32_t in_addr_t;
​失败,返回INADDR_NONE (usually -1);

6.2网络字节序--->点分十进制

1)inet_ntoa 常用

头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

原型:

char *inet_ntoa(struct in_addr in);

参数:

struct in_addr in:指定要转换成点分十进制字符串的IP地址;
           typedef uint32_t in_addr_t;
           struct in_addr {
               in_addr_t s_addr;
           };

返回值:

成功,返回点分十进制字符串的首地址;

2)inet_ntop

头文件:

#include <arpa/inet.h>

原型:

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

参数:

 int af:协议族
            AF_INET         IPV4
            AF_INET6        IPV6
 void* src:存储要转换成点分十进制字符串的IP首地址;
           typedef uint32_t in_addr_t;
           struct in_addr {
               in_addr_t s_addr;
           };
​
            af == AF_INETa;
            struct in6_addr
            {
            }
 char *dst:存储转换后的结果,点分十进制的首地址;
 socklen_t size:缓冲区大小,其实就是指定多大的空间用于转换IP;

返回值:

成功,返回字符串的首地址,就是dst;
失败,返回NULL,更新errno;   

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

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

相关文章

基于IMX6ULLmini的linux裸机开发系列九:时钟控制模块

时钟控制模块 核心 4个层次配置芯片时钟 晶振时钟 PLL与PFD时钟 PLL选择时钟 根时钟/外设时钟 系统时钟来源 RTC时钟源&#xff1a;32.768KHz 系统时钟&#xff1a;24MHz&#xff0c;作为芯片的主晶振使用 PLL和PFD倍频时钟 7路锁相环电路&#xff08;每个锁相环电路…

Maven打包后的jar文件只有几kb情况解决方法

1、pom文件添加如下代码 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> 2、打开ide的maven工具侧边栏…

solidwords(5)

我们打算从上面画出总体&#xff0c;再从上面、侧面切除 最后成品

Java网络编程(二)NIO实现简易的多人聊天

服务端实现 package com.bierce.io; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; //服务器端 public cl…

红绿灯识别、倒计时识别(毕业设计)

交通标志识别 本项目使用YOLO 模型&#xff0c;并在对数字信号灯进行数字识别时采用opencv算法。 环境安装 所需环境 python 3.7.11 torch1.2.00 使用 pip install -r requirements.txt安装所需的包。 文件下载 训练所需的预训练权重可在百度网盘中下载。 链接&#xf…

ARM体系结构学习笔记:任何算法可通过下面的三种模式组合而成

任何算法可通过下面的三种模式组合而成 条件跳转和无条件跳转 条件命名规则 关于比较的一些哲学问题 汇编实现if else [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R8R5cYTQ-1692236026691)(https://cdn.jsdelivr.net/gh/nzcv/picgo/202201172242…

Gin+微服务实现抖音视频上传到七牛云

文章目录 安装获取凭证Gin处理微服务处理 如果你对Gin和微服务有一定了解&#xff0c;看本文较容易。 安装 执行命令&#xff1a; go get github.com/qiniu/go-sdk/v7获取凭证 Go SDK 的所有的功能&#xff0c;都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的A…

回归预测 | MATLAB实现BES-LSSVM秃鹰搜索算法优化最小二乘支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-LSSVM秃鹰搜索算法优化最小二乘支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-LSSVM秃鹰搜索算法优化最小二乘支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&a…

手写模拟SpringBoot核心流程(二):实现Tomcat和Jetty的切换

实现Tomcat和Jetty的切换 前言 上一篇文章我们聊到&#xff0c;SpringBoot中内置了web服务器&#xff0c;包括Tomcat、Jetty&#xff0c;并且实现了SpringBoot启动Tomcat的流程。 那么SpringBoot怎样自动切换成Jetty服务器呢&#xff1f; 接下来我们继续学习如何实现Tomcat…

网络编程面试笔试题

一、OSI 7层模型&#xff0c;TCP/IP 4层模型 5层模型。 以及每一层的功能&#xff08;重点&#xff1a;第三层 第四层&#xff09; 答&#xff1a; 7层模型&#xff08;①物理层&#xff1a;二进制比特流传输&#xff0c;②数据链路层&#xff1a;相邻结点的可靠传输&#xf…

Ctfshow web入门 命令执行RCE篇 web29-web77 与 web118-web124 详细题解 持续更新中

Ctfshow 命令执行 web29 pregmatch是正则匹配函数&#xff0c;匹配是否包含flag&#xff0c;if(!preg_match("/flag/i", $c))&#xff0c;/i忽略大小写 可以利用system来间接执行系统命令 flag采用f*绕过&#xff0c;或者mv fl?g.php 1.txt修改文件名&#xff0c…

Docker搭建LNMP----(超详细)

目录 ​编辑 一、项目环境 1.1 所有安装包下载&#xff1a; 1.3 服务器环境 1.4任务需求 二、Ngin 2.1、建立工作目录 2.2 编写 Dockerfile 脚本 2.3准备 nginx.conf 配置文件 2.4生成镜像 2.5创建自定义网络 2.6启动镜像容器 2.7验证 nginx、 三、Mysql 3.1建立…

生产环境下的终极指南:使用 Docker 部署 Nacos 集群和 MySQL

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

WPF入门到精通:1.新建项目及项目结构

WPF&#xff08;Windows Presentation Foundation&#xff09;是一种用于创建 Windows 应用程序的技术&#xff0c;它可以通过 XAML&#xff08;Extensible Application Markup Language&#xff09;和 C# 或其他 .NET 语言来实现。WPF 提供了许多强大的 UI 控件和样式&#xf…

OpenCV实例(九)基于深度学习的运动目标检测(二)YOLOv2概述

基于深度学习的运动目标检测&#xff08;二&#xff09;YOLOv2&YOLOv3概述 1.YOLOv2概述2.YOLOv3概述2.1 新的基础网络结构&#xff1a;2.2 采用多尺度预测机制。2.3 使用简单的逻辑回归进行分类 1.YOLOv2概述 对YOLO存在的不足&#xff0c;业界又推出了YOLOv2。YOLOv2主要…

17.HPA和rancher

文章目录 HPA部署 metrics-server部署HPA Rancher部署Rancherrancher添加集群仪表盘创建 namespace仪表盘创建 Deployments仪表盘创建 service 总结 HPA HPA&#xff08;Horizontal Pod Autoscaling&#xff09;Pod 水平自动伸缩&#xff0c;Kubernetes 有一个 HPA 的资源&…

openai多模态大模型:clip详解及实战

引言 CLIP全称Constrastive Language-Image Pre-training&#xff0c;是OpenAI推出的采用对比学习的文本-图像预训练模型。CLIP惊艳之处在于架构非常简洁且效果好到难以置信&#xff0c;在zero-shot文本-图像检索&#xff0c;zero-shot图像分类&#xff0c;文本→图像生成任务…

728. 自除数 题解

题目描述&#xff1a;728. 自除数 - 力扣&#xff08;LeetCode&#xff09; 自除数 是指可以被它包含的每一位数整除的数。 例如&#xff0c;128 是一个 自除数 &#xff0c;因为 128 % 1 0&#xff0c;128 % 2 0&#xff0c;128 % 8 0。 自除数 不允许包含 0 。 给定两个整…

VCS与Verdi联仿,简要万能工程模板,持续更新中...

VCS与Verdi联仿&#xff0c;简要工程模板&#xff0c;持续更新中… 文章目录 VCS与Verdi联仿&#xff0c;简要工程模板&#xff0c;持续更新中...背景编写工程模块使用工程模板仿真结果工程下载地址 背景 学习verilog&#xff0c;故用vcs来编译verilog&#xff0c;用verdi来查…

一篇文章了解编译类成员定义

文章目录 一篇文章了解编译类成员定义 %Dictionary.CompiledClass - 编译类定义表简介索引示例表结构 %Dictionary.CompiledConstraint - 编译约束表简介索引示例表结构 %Dictionary.CompiledConstraintMethod - 编译约束表简介索引示例表结构 %Dictionary.CompiledForeignKey …