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

【Linux网络编程基础--socket地址API】

一、主机字节序和网络字节序

  • 主机字节序(Host Byte Order):你当前电脑的内存字节顺序(比如 x86 是小端)

  • 网络字节序(Network Byte Order):统一规定为大端序(高位字节在高位地址,比较符合人类阅读习惯。)

测试电脑是什么字节序

void char_testByte()
{unsigned int i=0x1200;char *ptr=(char*)&i;if(*ptr)printf("Big\n");else printf("Little\n");}

对于两台使用不同字节序的主机,他们俩之间传输数据时,必然会错误的解释。因此规定大端字节序为网络字节序,以作为共同的一个标准。

Linux提供了如下4个函数来完成主机字节序和网络字节序之间的转换:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);		
//host to network long:把32bit的主机序转换到网络序
uint16_t htons(uint16_t hostshort);		
//把16bit的主机序转换到网络序
uint32_t ntohl(uint32_t netlong);		
//network to host long:把32bit的网络序转换到主机序
uint16_t ntohs(uint16_t netshort);	
//把16bit的网络序转换到主机序

二、socket地址

  1. UNIX本地域协议族使用下面这个专用socket地址结构体
struct sockaddr_un {sa_family_t sun_family;    // AF_UNIXchar sun_path[108]; // 套接字路径(如 "/tmp/my_socket")
};
  1. TCP/IP协议族的专用socket地址结构体如下
  • IPv4
#include <netinet/in.h>  // 头文件struct sockaddr_in {sa_family_t    sin_family;   // 地址族(AF_INET)in_port_t      sin_port;     // 16位端口号(需用 htons() 转换字节序)struct in_addr sin_addr;     // 32位 IPv4 地址char           sin_zero[8];  // 填充字段(未使用,通常置 0)
};struct in_addr {in_addr_t      s_addr;       // 32位 IPv4 地址(需用 htonl() 转换字节序)
};
  • IPv6
#include <netinet/in.h>struct sockaddr_in6 {sa_family_t     sin6_family;   // 地址族(AF_INET6)in_port_t       sin6_port;     // 16位端口号(需用 htons() 转换)uint32_t        sin6_flowinfo; // 流标签(通常为 0)struct in6_addr sin6_addr;     // 128位 IPv6 地址uint32_t        sin6_scope_id; // 接口作用域 ID(用于链路本地地址)
};struct in6_addr {unsigned char   s6_addr[16];   // 128位 IPv6 地址
};
  1. IP地址转换函数
    1. 1 所需头文件
#include<arpa/inet.h>
    1. 2 inet_pton函数:把点分十进制字符串表示的IP地址转成网络字节序表示的IP地址,结果存放在dst所指向的内存。
int inet_pton(int af,const char * src,void* dst);

官方文档
在这里插入图片描述
代码测试

void test_inet_pton()
{const char *ip_str = "192.168.0.1";struct in_addr addr;int ret = inet_pton(AF_INET, ip_str, &addr);if (ret == 1) {printf("[inet_pton] 成功将字符串 \"%s\" 转换为二进制地址\n", ip_str);printf("[inet_pton] 网络字节序(十六进制): 0x%x\n", ntohl(addr.s_addr));//先把二进制表示的转换成十六进制形式,也就是网络字节序。(不能直接输出二进制)} else if (ret == 0) {printf("[inet_pton] 输入地址无效: %s\n", ip_str);} else {perror("[inet_pton] 转换出错");}
}
    1. 3 inet_ntop函数:把网络字节序表示的IP地址转化成点分十进制表示的IP地址
const char* inet_ntop(int af,const void* src,char* dst,socklen_t cnt);

在这里插入图片描述
代码测试

void test_inet_ntop()
{struct in_addr addr;addr.s_addr = htonl(0xC0A80001);  // 十进制 192.168.0.1 的网络字节序char ip_str[INET_ADDRSTRLEN];const char *result = inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));if (result != NULL) {printf("[inet_ntop] 成功将二进制地址转换为字符串: %s\n", ip_str);} else {perror("[inet_ntop] 转换出错");}
}

运行结果
在这里插入图片描述

http://www.dtcms.com/a/313403.html

相关文章:

  • 多 4G 通讯模组共存时的干扰问题深度解析与解决方案
  • leecode-每日一题-2106. 摘水果
  • vmfusion启动centos6.10 一直卡到call 169.254.169.254
  • 全面解析 BGE Embedding 模型:训练方式、模型系列与实战用法
  • Redis——常用指令汇总指南(三)(哈希类型)
  • 编写xsync集群分发脚本(保姆级别)
  • Redis 数据同步机制
  • 【Linux】Makefile Cmake—基操
  • [特殊字符]字节Get!免费进楼攻略速存[特殊字符]
  • LWIP从FreeRTOS到uC/OS-III的适配性改动
  • linux 扩展未分配的磁盘空间到home下
  • SQL157 更新记录(一)
  • 代码随想录算法训练营第五十八天|动态规划part8
  • 成功解决ImportError: DLL load failed while importing _multiarray_umath: 找不到指定的模块。
  • 深度学习中的模型知识蒸馏
  • 深度学习中卷积与互相关
  • 记录使用ruoyi-flowable开发部署中出现的问题以及解决方法
  • FastAPI-Vue3-Admin 一款Python 全栈融合的高可用中后台快速开发平台方案
  • golang 函数选项模式
  • 数据结构(概念及链表)
  • 【数据结构】队列的顺序存储与链式存储(C语言版)
  • 基于深度学习的医学图像分析:使用变分自编码器(VAE)实现医学图像生成
  • (FD Conv)Frequency Dynamic Convolution for Dense Image Prediction论文精读(逐段解析)
  • 07.config 命令实现动态修改配置和慢查询
  • [硬件电路-138]:模拟电路 - 什么是正电源?什么是负电源?集成运放为什么有VCC+和VCC-
  • Unix 发展史概览
  • 探索 Zephyr 项目:高效、可扩展的实时操作系统
  • 源代码本地安装funasr
  • C语言数据结构(6)贪吃蛇项目1.贪吃蛇项目介绍
  • 有限元方法中的数值技术:三角矩阵求解