sockaddr_in与sockaddr的区别,以及对网络字节序和主机字节序的理解和转换函数

2023-05-16

一、sockaddr

sockaddr在/usr/include/bits/socket.h下,查看sockaddr的结构:

struct sockaddr
  {
    __SOCKADDR_COMMON (sa_);    /* Common data: address family and length.     协议族 */
    char sa_data[14];           /* Address data.  地址+端口号*/
  };

sockaddr的缺陷:sa_data把目标地址和端口信息混在一起了。而sockaddr_in就解决了这一缺陷,将端口号和IP地址分开存储。

二、sockaddr_in

sockaddr_in在/usr/include/netinet/in.h下,
查看sockaddr_in的结构:

struct sockaddr_in
   {
     __SOCKADDR_COMMON (sin_);/* Common data: address family and length.     协议族 */
     in_port_t sin_port;                    /* Port number.  16位端口号*/
    struct in_addr sin_addr;            /* Internet address.  32位IP地址*/

     /* Pad to size of `struct sockaddr'.  用于填充的0字节*/
    unsigned char sin_zero[sizeof (struct sockaddr) -
                            __SOCKADDR_COMMON_SIZE -
                            sizeof (in_port_t) -
                           sizeof (struct in_addr)];
   };

typedef uint32_t in_addr_t;
 struct in_addr
 {
     in_addr_t s_addr;       //32位IPV4地址
  };

 /* Ditto, for IPv6.  */
struct sockaddr_in6
   {
    __SOCKADDR_COMMON (sin6_);
     in_port_t sin6_port;        /* Transport layer port # */
    uint32_t sin6_flowinfo;     /* IPv6 flow information */
     struct in6_addr sin6_addr;  /* IPv6 address */                          
   uint32_t sin6_scope_id;     /* IPv6 scope-id */
   };

三、两者之间的区别与联系

我们来看一下sockaddr_in与sockaddr的结构:
这里写图片描述
联系:二者的占用的内存大小是一致的,因此可以互相转化,从这个意义上说,他们并无区别。
区别:sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。
而sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作。使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。

举个简单的例子:

int main()
 {
     int sock = socket(AF_INET, SOCK_STREAM, 0);//获得fd
     if(sock < 0){                                                           
         printf("create sock error\n");
     }

    struct sockaddr_in my_socket;
    bzero(&server_socket,sizeof(server_socket));//初始化结构体
    my_socket.sin_family = AF_INET;//设置协议家族
    my_socket.sin_addr.s_addr = htonl(INADDR_ANY);//设置IP地址
    my_socket.sin_port = htons(PORT);//设置端口号

    bind(sock, (struct sockaddr*)&server_socket, sizeof(struct soc   kaddr_in));//绑定
...
}

可以看到在初始化类型为sockaddr_in的结构体时,调用了htons函数和inet_addr函数。
htons函数将端口号由主机字节转换为网络字节序的整数值。
inet_addr函数将一个IP字符串转换为一个网络字节序的整数值。

四、网络字节序与主机字节序

1.主机字节序
就是我们平常说的大端和小端模式,大端就是低地址存放高字节,小端就是低地址存放低字节。不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。
2.网络字节序
内存地址有大小端之分,网络数据流同样有大端小端之分。发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。
举个例子:4个字节的32bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这就是大端字节序。也就是TCP/IP首部中所有的二进制整数在网络中传输时都要求的这种次序。

主机字节序与网络字节序的转换函数

#include <arpa/inet.h>

/*将32位的长整数从主机字节序转换为网络字节序,*/ 
uint32_t htonl(uint32_t hostlong);
 /*将16位的短整数从主机字节序转换为网络字节序,*/
  uint16_t htons(uint16_t hostshort); 
 /*将32位的长整数从网络字节序转换为主机字节序,*/
  uint32_t ntohl(uint32_t netlong); 
 /*将16位的短整数从网络字节序转换为主机字节序,*/ 
 uint16_t ntohs(uint16_t netshort);

这样记忆,h代表host(本地主机),n代表net(网络),l是unsigned long(无符号长整型)。

如果是小端字节序,这些函数就会将参数转换为大端返回,如果是大端字节序,不做转换,直接返回。

我们一般为了简化编程,将IP地址设置为INADDR_ANY,如果需要使用特定的IP地址则需要使用inet_addr 和inet_ntoa完成字符串和in_addr结构体的互换,in_addr是SOCKADDR_IN成员,其代表IP地址。

五、inet_addr函数&inet_nota函数

//inet_addr函数
unsigned long inet_addr(const char* cp);//cp代表点分十进制

//inet_nota函数
char* inet_nota(struct in_addr in);

举个例子:

 SOCKADDR_IN sock;  
 sock.sin_family = AF_INET;  
 //将字符串转换为in_addr类型  
 sock.sin_addr.S_un.S_addr =  inet_addr("192.168.1.111");  
 sock.sin_port = htons(5000);  

 //将in_addr类型转换为字符串  
 printf("inet_ntoa ip = %s\n",inet_ntoa(sock.sin_addr));

结果:inet_ntoa ip =192.168.1.111

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sockaddr_in与sockaddr的区别,以及对网络字节序和主机字节序的理解和转换函数 的相关文章

  • Raspberry Pi Pico C/C++语言在Windows环境下开发环境搭建 Raspberry Pi Pico C/C++ SDK

    目录 前言Raspberry Pi Pico介绍需要支持的软件软件安装配置及注意事项ARM GCC compiler的安装CMake的安装Git 安装Visual Studio 2019的安装Visual Studio Code的配置Pyt
  • 【LoRa32U4II】介绍以及基于Arduino IDE编译环境搭建及测试

    目录 LoRa 模块LoRa32u4 II介绍LoRa32u4 II 资料下载LoRa32u4 II 规格介绍LoRa32u4 II 脚位说明 编译环境介绍电脑系统编译软件Arduino需求库 编译环境搭建及测试LoRa32u4 II 测试
  • 【Benewake(北醒) 】短距 TF-LC02 2m资料整理

    目录 1 TF LC02简要说明1 1 性能参数1 2产品图片及尺寸 2 运用2 1 在开源板Arduino上的运用2 2 在Python上的应用 1 TF LC02简要说明 1 1 性能参数 1 2产品图片及尺寸 2 运用 2 1 在开源
  • 【Arduino】Benewake(北醒) TF-LC02(TTL)基于Arduino 开发板运用说明

    目录 前言Benewake 北醒 TF LC02产品简要说明Arduino开发板介绍Benewake 北醒 TF LC02 接口及通讯协议说明接口定义串口协议说明通讯协议说明功能码说明 接线示意图例程说明配置软硬串口定义获取TOF数据的结构
  • 【Benewake(北醒) 】中距 TF02-i 40m工业版本CAN/485介绍以及资料整理

    目录 1 前言2 产品介绍3 产品快速测试3 1 产品规格书及使用说明书3 2 通用指令串口助手使用说明3 3 产品快速测试说明 4 基于开源硬件的运用整理4 1 在开源飞控上的运用 5 基于其他的运用整理5 1 在PLC上的运用说明5 2
  • 【ESP32 DEVKIT_V1】基于Arduino IDE环境搭建

    目录 一 前言二 板子介绍三 环境搭建1 Arduino IDE的安装2 在Arduino IDE上添加外包链接3 添加好外包链接后就可以下载对应的板子库文件 测试1 先把开发板接到电脑 xff0c 并在Arduino IDE上选择对应的开
  • 【ESP32 DEVKIT_V1】北醒TF系列雷达在ESP32 DEVKIT_V1开发板上的运用

    目录 前言一 硬件准备二 硬件接线说明串口接线示意图 xff1a I2C接先示意图 三 软件搭建及测试1 使用Arduino IDE编译教程2 使用vsCode 43 Arduino教程2 1 在vsCode上使用Arduino的环境搭建2
  • 【vsCode + Arduino】在Visual Studio Code编译Arduino项目

    目录 前言一 参考文档二 操作步骤2 1 安装Arduino IDE2 2 在vsCode里安装Arduino插件2 3 配置arduino的安装路径2 4 配置好后打开一个Arduino的项目文件夹进行相应的配置 三 目前已知问题 前言
  • 蓝牙:GATT,属性,特性,服务

    接着上一篇 通用属性配置文件 xff08 Generic Attribute Profile xff09 1 GATT简介 通用属性配置文件Generic Attribute Profile简称GATT GATT定义了属性类型并规定了如何使
  • RS232 RS422 RS485详细介绍

    1 RS 232 C RS 232 C是美国电子工业协会EIA xff08 Electronic Industry Association xff09 制定的一种串行物理接口标准 RS是英文 推荐标准 的缩写 xff0c 232为标识号 x
  • stm32串口使用以及串口中断接收不定长度字符串

    开始使用cubemx配置PA9 PA10分别为TX RX端 xff0c 在使能串口中断 之后其余值直接使用默认的就可以了 点击生成代码即可 span class token class name uint8 t span rx buff s
  • STM32-串口通信printf重定向

    前言 xff1a 平时我们进行c语言编程的时候会经常用到printf函数进行打印输出 xff0c 来调试代码 可是这个printf函数C库已经帮我们实现好了 xff0c 通常只需要直接调用即可 xff0c 但是如果在一个新的开发平台 xff
  • FMCW毫米波雷达原理

    Radar系列文章 传感器融合是将多个传感器采集的数据进行融合处理 xff0c 以更好感知周围环境 xff1b 这里首先介绍毫米波雷达的相关内容 xff0c 包括毫米波雷达基本介绍 xff0c 毫米波雷达数据处理方法 xff08 测距测速测
  • VMware虚拟机安装ubuntu16.04系统教程

    对于没有接触过Ubuntu系统的小伙伴来说 xff0c 直接在物理机上安装Ubuntu单系统或者windows Ubuntu双系统一件比较刺激的事情 xff0c 因为一不小心可能就会把电脑整崩溃 xff0c 或者出现各种问题 xff0c 所
  • c#实验五 文件与流

    实验五 文件与流 WPF还不太会 抄STZG的 xff0c 其他自己写的 一 实验目的 掌握文件类的使用 xff1b 掌握文件流的操作 xff1b 掌握二进制数据 文本数据的读写 xff1b 继续应用WPF技术进行界面编程 二 实验内容 要

随机推荐