Linux网络编程套接字地址结构和字节操作函数

news/2024/4/25 20:18:07/文章来源:https://blog.csdn.net/m0_49476241/article/details/130255099

文章目录

  • 前言
  • 一、IPV4套接字地址结构
  • 二、通用套接字地址结构
  • 三、字节操作函数
    • 1.网络字节序主机字节序转换函数
    • 2.地址转换函数
      • 1.inet_aton、inet_addr、inet_ntoa函数
      • 2.inet_pton、inet_ntop函数
  • 4.编程实验
  • 总结


前言

本篇文章将给大家介绍套接字地址结构和字节操作函数的使用。

一、IPV4套接字地址结构

IPV4套接字地址结构通常也称为"网际套接字地址结构"它以sockaddr_in命名。定义在<in.h>头文件中。

sin_family:表示协议族,一般为AF_INET。
sin_port:表示端口号,需要以网络字节序存储,通常使用htons()函数进行转换。
sin_addr:表示IP地址,类型为in_addr结构体指针,也需要以网络字节序存储。可以使用inet_aton()或inet_addr()函数进行转换,或者手动设置。
sin_zero:用于填充,保证长度为sockaddr的长度。

/* Structure describing an Internet socket address.  */
struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port;			/* Port number.  */struct in_addr sin_addr;		/* Internet address.  *//* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};

前面的客户端和服务端编程我们都对这个结构体进行设置。这里我们详细讲解一下客户端和服务端是如何设置这个结构体的参数的。

客户端:
sin_family设置为AF_INET代表使用的是IPV4协议。
sin_port代表端口号这里设置为了8888
sin_addr代表客户端要连接服务端的IP地址

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{printf("inet_pton is err\n");
}

服务端:
服务端和客户端最大的区别就是在s_addr 的设置上。

INADDR_ANY是一个常量,它的值是0,定义在头文件<netinet/in.h>中。它的作用是让套接字可以监听任意IP地址,这通常在多网卡机器或者服务端需要监听多个网络接口时使用。

 saddr.sin_family = AF_INET;saddr.sin_addr.s_addr = htonl(INADDR_ANY);saddr.sin_port = htons(8888);

二、通用套接字地址结构

套接字通用地址结构通常用于存储网络地址和端口号等信息,它的定义如下:

struct sockaddr {unsigned short sa_family; // 地址族(Address Family)char sa_data[14];         // 可变长度的地址数据
};

看到之前的编写的程序是如何使用到这个通用套接字地址结构的:

bind(server, (struct sockaddr*)&saddr, sizeof(saddr))

这个saddr我们在编写代码的时候是使用的IPV4的地址结构。在使用bind函数时第二个参数需要指定为套用套接字地址结构,所以这里需要进行一个强制类型转换。
将IPV4套接字地址结构改变为套用套接字地址结构。

为什么要把IPV4地址结构转换为通用套接字地址结构呢?

因为 BSD socket API 可以同时支持 IPv4 和 IPv6 网络协议族,而这些网络协议族的地址结构可能不同。所以需要用 struct sockaddr 结构体体现通用性,便于能够适配多个协议族的网络地址结构。

三、字节操作函数

1.网络字节序主机字节序转换函数

htons和htonl都是指网络字节序和主机字节序之间的转换函数。在计算机网络中,网络字节序是一种通用的数据表示形式,它用于在互联网上传输数据。不同的计算机体系结构使用不同的字节序,即大端字节序和小端字节序。网络字节序是一种统一的字节序,它与主机字节序不同。因此,在发送和接收网络数据时,必须将数据从主机字节序转换为网络字节序,并在接收数据时将其转换回主机字节序。htons和htonl是用于这种转换的函数。

htons和htonl都是位于arpa/inet.h头文件中的函数。htons函数的作用是将主机字节序的16位整数转换为网络字节序的16位整数。htonl函数的作用是将主机字节序的32位整数转换为网络字节序的32位整数。

代码的使用:
这里是将8888这个端口号从主机字节序转换为了网络字节序。

servaddr.sin_port = htons(8888);

2.地址转换函数

我们熟知的地址一般是以字符串的形式出现的例如:“206.168.112.96”
但是在网络中进行通信时需要把字符串形式的IP地址转换为二进制类型的地址。
将字符串地址转换成二进制地址是为了在网络中让设备能够准确识别和处理数据包,从而实现正确的数据传输。

1.inet_aton、inet_addr、inet_ntoa函数

在man手册中都可以查看到这些函数的具体用法。
inet_aton:

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

inet_aton函数将一个点分十进制的IP地址转换成一个32位的整数,并将结果存储在指向结构体in_addr的指针中。其操作非常简单,直接输入一个字符串形式的IP地址,指定一个in_addr结构体类型的指针,即可完成ip字符串转整数的转换,如果转换成功则返回非零值(1),否则返回 0。
inet_addr

in_addr_t inet_addr(const char *cp);

inet_addr函数与inet_aton函数类似,同样是把以点分十进制表示的字符串IP地址转换成32位的网络字节序整数。它的返回值是一个in_addr_t类型的整数,若调用失败则返回-1。
inet_ntoa

char *inet_ntoa(struct in_addr in)

inet_ntoa函数则将一个32位二进制整数转换成一个点分十进制IP地址的字符串。其传入一个in_addr结构体类型的数据,即可得到相应的IP字符串,如果转换成功,则返回表示该字符串IP地址的指针,否则返回 NULL。需要注意的是,由于inet_ntoa函数的返回值是一个指向静态存储区的指针,所以多次调用该函数时需要在调用存储之间将其复制到一个缓冲区中。

2.inet_pton、inet_ntop函数

这两个函数是随着IPV6的出现而出现的函数。在IPV4和IPV6都是适用的。

inet_pton:

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

inet_pton函数用于将IPv4或IPv6地址字符串转换为网络字节序的二进制格式。
其中,af表示地址族(AF_INET代表IPv4地址族,AF_INET6代表IPv6地址族),src是一个字符串,表示待转换的IP地址,dst是一个指向存储转换后结果的内存单元的指针。

inet_ntop:

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

inet_ntop函数则用于将网络字节序的IPv4或IPv6地址转换为可读的地址字符串。
其中,af表示地址族(AF_INET代表IPv4地址族,AF_INET6代表IPv6地址族),src是指向网络字节序的二进制形式的地址的结构体指针,dst是存储转换后结果的缓冲区指针,size表示缓冲区大小。

4.编程实验

这里我们只使用inet_pton和inet_ntop这两个函数进行实验。其他的函数大家可以自己去尝试。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>#define INET_ADDRSTRLEN 100int main() {struct in_addr addr;char ip_str[INET_ADDRSTRLEN];// 将IP地址从字符串转换为二进制形式if (inet_pton(AF_INET, "192.168.1.1", &addr) != 1) {printf("inet_pton");}// 将二进制形式的IP地址转换为字符串const char *ret = inet_ntop(AF_INET, &addr, ip_str, INET_ADDRSTRLEN);if (ret == NULL) {printf("inet_ntop");}printf("IPv4 address: %s\n", ip_str);return 0;
}

上述代码中,inet_pton函数将IPv4地址从字符串转换为二进制形式,inet_ntop函数将二进制形式的IP地址转换为字符串,并将结果存储在ip_str数组中。其中,INET_ADDRSTRLEN是一个宏定义,表示IPv4地址字符串的最大长度。如果转换失败,inet_pton或inet_ntop函数会返回-1,并设置errno值。

总结

本篇文章主要介绍了通用套接字地址结构和IPV4套接字地址结构,以及字节操作函数的使用。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑突然变成绿屏错误代码无法使用怎么办?

电脑突然变成绿屏错误代码无法使用怎么办&#xff1f;有用户使用电脑的时候&#xff0c;电脑桌面变成了绿屏的显示&#xff0c;所有的操作无法继续进行。遇到这个问题要怎么去进行解决呢&#xff1f;来看看详细的解决方法教学吧。 准备工作&#xff1a; 1、U盘一个&#xff08;…

(原创)Flutter基础入门:手把手教你搭建Flutter混合项目

前言 Flutter是Google开源的构建用户界面&#xff08;UI&#xff09;工具包 支持在不同平台构建一致的ui效果 但在实际业务中&#xff0c;一般不会整个APP都用纯Flutter开发 尤其一些老的项目&#xff0c;会采用接入Flutter的方式来混合开发 那么今天就主要讲一下如何搭建一个…

SQLServer:Win/Linux环境安装及一键部署脚本

1. Win安装SQLServer CSDN已有完整安装流程&#xff0c;亲测可用。----》Windows安装SQLServer流程 2. Linux安装 SQLServer 2.1 设置镜像 curl https://packages.microsoft.com/config/rhel/7/mssql-server-2017.repo > /etc/yum.repos.d/mssql-server.repo 2.2 通过y…

深度学习模型参数量与训练数据量的平衡对泛化性能的影响

一、引言 深度学习模型在计算机视觉、自然语言处理等领域取得了显著的成果。为了获得泛化性能良好的模型&#xff0c;研究者需要在模型复杂度和训练数据量之间找到合适的平衡。本文将探讨这两者之间的关系以及如何在实际应用中实现最佳效果。 二、模型复杂度与训练数据量的关…

史上最严宝宝口粮新国标出台,DHA和维生素D可能无需额外补充了

自2023年2月22日起&#xff0c;我国婴幼儿配方食品&#xff08;以下简称配方奶&#xff09;新国标开始实施。这意味着2023年2月22日以后在中国上架销售的配方奶必须符合新国标&#xff0c;重新取得国家市场监督管理总局食品评审中心&#xff08;CFE-SAMR&#xff09;的注册。这…

改变思想,拥抱毒瘤,让公司走的更远

牛B的人物&#xff0c;早已经厌倦了中英文混杂&#xff0c;他们更进一步&#xff0c;使用中英文缩写&#xff0c;对普通人进行降维打击。更厉害的&#xff0c;造就新的名词&#xff0c;并科普出去。 有几项技术&#xff0c;我从心底里鄙视和厌恶&#xff0c;但每次在技术方案中…

【MCAL_Uart】-1.1-图文详解Uart串口协议

目录 1 什么是UART 2 UART的电平 3 UART的波特率 4 UART帧格式 4.1 start bit起始位 4.2 data bit数据位 4.3 parity bit奇偶校验位 4.4 stop bit停止位 5 什么是8-N-1 6 UART总线负载率计算 结尾 优质博文推荐阅读&#xff08;单击下方链接&#xff0c;即可跳转&am…

Linux驱动之在Ubuntu下编译驱动模块——学习笔记(12)

为了方便驱动开发学习&#xff0c;了解一下在Ubuntu上进行驱动编译的流程。 一、下载对应的内核源码 首先要通过 uname -a查询一下自己的内核版本。 我这里下载的是 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.tar.gz 二、编译内核 &#xff08;1&a…

功能安全ISO26262 道路车辆 功能安全审核及评估方法第3部分:软件层面

道路车辆 功能安全审核及评估方法 第3部分&#xff1a;软件层面 Road vehicles - Functional Safety Audit and Assessment Method - Part 3: Software Level &#xff08;工作组草案&#xff09; 2022.4.15 前  言 本文件按照GB/T 1.1—2020《标准化工作导则 第1部分…

Pytorch深度学习笔记(十)多分类问题

课程推荐&#xff1a;09.多分类问题_哔哩哔哩_bilibili 目录 1. 多分类模型 2. softmax函数模型 3. Loss损失函数 4.实战MNIST Dataset 之前&#xff0c;在逻辑斯蒂回归中我们提到了二分类任务&#xff0c;现在我们讨论多分类问题。 1. 多分类模型 与二分类不同的是多分…

Hive基础和使用详解

文章目录 一、启动hive1. hive启动的前置条件2. 启动方式一: hive命令3. 方式二:使用jdbc连接hive 二、Hive常用交互命令1. hive -help 命令2. hive -e 命令3. hive -f 命令4. 退出hive窗口5. 在hive窗口中执行dfs -ls /&#xff1b; 三、Hive语法1.DDL语句1.1 创建数据库1.2 两…

Redis 数据存储原理

核心模块如图 1-10。 图1-10 图 1-10 Client 客户端&#xff0c;官方提供了 C 语言开发的客户端&#xff0c;可以发送命令&#xff0c;性能分析和测试等。 网络层事件驱动模型&#xff0c;基于 I/O 多路复用&#xff0c;封装了一个短小精悍的高性能 ae 库&#xff0c;全称是 …

【人工智能】遗传算法

人工智能算法---遗传算法&#xff08;基础篇&#xff09; 知识导图&#xff1a;遗传算法&#xff08;概念&#xff09;1.初始化种群二进制编码与解码 2.选择操作3.交叉操作4.评估操作5.终止操作 知识导图&#xff1a; 遗传算法&#xff08;概念&#xff09; 可以把遗传算法类比…

Docker 快速入门

1、Docker 简介 Docker是一个开源的容器引擎&#xff0c;它可以帮助我们更快地交付应用。Docker可将应用程序和基础设施层隔离&#xff0c;并且能将基础设施当作程序一样进行管理。使用Docker&#xff0c;可更快地打包、测试以及部署应用程序&#xff0c;并可减少从编写到部署…

python的智能换行函数(一堆烦乱的判断)

def zntxt(txt):line30 #设置单行长度js,e,s,rs,aa,nm,x,y{},[],txt,[],,[],0,0n 1 if ord(s[0]) > 127 else 0for i in range(len(s)):m1 if ord(s[i]) > 127 else 0if m!n:rs.append(aa)aas[i]elif ilen(s)-1:aas[i]rs.append(aa)else:aas[i]nmfor i in rs: for j in…

搜索引擎找外贸客户

说起搜索引擎&#xff0c;我们每个人都不陌生&#xff0c;也许第一时间就能想到平日经常使用的“百度一下”和凭借强大算法及丰富功能占据近85%市场份额的谷歌搜索&#xff08;Statista 2023年1月数据&#xff09;这些耳熟能详的搜索引擎。对于外贸人而言搜索引擎也是非常实用的…

一文谈谈文心一言对比ChatGPT4.0的差距

对于想体验文心一言的朋友&#xff0c;可以进行申请尝试&#xff0c;快速入口 如果想体验ChatGPT的朋友&#xff0c;可以自行fq注册&#xff1b;但是由于现在限制注册并且不稳定&#xff0c;对于不会用梯子不想注册的朋友可以使用这个进行访问&#xff0c;快速入口 关于ChatG…

PMP证书备考攻略+PMP知识点汇总

一&#xff0c;考PMP好处多 1.能力提升 大型项目&#xff0c;领导专业团队 2.升职加薪 晋升管理岗&#xff0c;优先升职加薪 3.招投标加分 具有PMP证书&#xff0c;企业招标有加分 4.转型利器 助力转型&#xff0c;拓宽职业发展 5.公司支持 企业鼓励学习&#xff0c;报销费用 6…

C++模板使用

感谢你的阅读&#xff01;&#xff01;&#xff01; 目录 感谢你的阅读&#xff01;&#xff01;&#xff01; 举个例子&#xff1a; template 有什么意义为什么要用模板 与typedef的区别 使用方法 模板&#xff1a;隐式实例化与显示实例化 和非模板函数以及多个模板类…