muduo网络库剖析——网络地址InetAddress类

muduo网络库剖析——网络地址InetAddress类

  • 前情
    • 从muduo到my_muduo
  • 概要
    • socketaddr_in
      • 介绍
      • 成员用法
    • 网络地址转换函数
  • 框架与细节
    • 成员
    • 函数
    • 使用方法
  • 源码
  • 结尾

前情

从muduo到my_muduo

作为一个宏大的、功能健全的muduo库,考虑的肯定是众多情况是否可以高效满足;而作为学习者,我们需要抽取其中的精华进行简要实现,这要求我们足够了解muduo库。

做项目 = 模仿 + 修改,不要担心自己学了也不会写怎么办,重要的是积累,学到了这些方法,如果下次在遇到通用需求的时候你能够回想起之前的解决方法就够了。送上一段话!

在这里插入图片描述

概要

socketaddr_in

介绍

sockaddr是一个用于存储套接字地址的结构体,它可以表示不同类型的地址,包括IPv4、IPv6等。它通常用于bind、connect、recvfrom和sendto等函数的参数,指明地址信息。然而,sockaddr结构体存在一些弊端,其中最主要的是sa_data字段将目标地址和端口信息混在一起,这导致在使用某些网络函数时需要额外的处理才能正确地获取地址和端口信息。

为了解决sockaddr的缺陷,出现了sockaddr_in结构体。与sockaddr相比,sockaddr_in结构体将port和addr分开储存在两个变量中,分别对应sin_port和sin_addr字段。这种结构使得地址和端口信息更加清晰,易于处理。同时,sockaddr_in结构体还提供了方便的函数来操作地址和端口信息,例如inet_pton和inet_ntop等。

总的来说,sockaddr_in相对于sockaddr具有更加清晰的结构和易于操作的字段,因此在网络编程中通常更受欢迎。虽然sockaddr仍然可以使用,但在处理IPv4地址时建议使用sockaddr_in结构体。
在这里插入图片描述

成员用法

  1. sin_family
    sin_family是sockaddr_in结构体中的一个字段,用于指定地址家族。在IPv4中,sin_family的值为AF_INET,表示使用IPv4地址。在IPv6中,sin_family的值为AF_INET6,表示使用IPv6地址。因此,sin_family字段用于指明地址类型,以便正确地处理和传输网络通信数据。
  2. sin_addr
    sin_addr是一个用于存储IP地址的字段,它是sockaddr_in结构体的一部分。sin_addr字段通常用于表示IPv4地址,使用无符号长整型(unsigned long)类型来存储32位的IP地址。通过使用inet_addr函数可以将字符串形式的IP地址转换为unsigned long类型的IP地址,并将其赋值给sin_addr字段。在处理网络通信时,sin_addr字段用于指明目标主机或服务器的IP地址,以便正确地建立连接和传输数据。需要注意的是,sin_addr字段的值应该以网络字节序存储,因为网络通信中通常使用网络字节序进行数据传输。
  3. sin_port
    sin_port是一个用于存储端口号的字段,它是sockaddr_in结构体的一部分。sin_port字段的数据类型是16位的无符号整数,用于表示端口号。端口号的取值范围通常为065535,其中01023为系统保留的端口号,一般由系统分配给特定的服务程序。用户可以使用1024~65535之间的端口号。在处理网络通信时,sin_port字段用于指明目标主机或服务器的端口号,以便正确地建立连接和传输数据。需要注意的是,sin_port字段的值应该以网络字节序存储,因为网络通信中通常使用网络字节序进行数据传输。如果需要在主机字节序和网络字节序之间进行转换,可以使用htons函数将主机字节序转换为网络字节序,使用ntohs函数将网络字节序转换为主机字节序。
  4. sin_zero
    sin_zero是一个通常不使用的字段,它是sockaddr_in结构体的一部分。sin_zero字段的存在只是为了与通用套接字地址结构struct sockaddr在内存中对齐,通常会被置为0。因此,在实际的网络编程中,很少使用sin_zero字段。

网络地址转换函数

  1. int inet_aton(const char *cp, struct in_addr *inp);
    inet_aton()将Internet主机地址cp从IPv4数字和点符号转换为二进制形式(以网络字节顺序),并将其存储在inp指向的结构中。Inet_aton()如果地址有效则返回非零,如果无效则返回零。
    如果提供的字符串被成功解释,Inet_aton()返回1,如果字符串无效(错误时没有设置errno)则返回0。
    在这里插入图片描述

  2. in_addr_t inet_addr(const char *cp);
    inet_addr()函数的作用是:将Internet主机地址cp从IPv4的数字点法转换为网络字节顺序的二进制数据。如果输入无效,则返回INADDR_NONE(通常为-1)。使用这个函数是有问题的,因为-1是一个有效的地址(255.255.255.255)。避免使用它,而应使用inet_aton()、inet_pton(3)或getaddrinfo(3),它们提供了一种更清晰的方式来指示错误返回。

  3. in_addr_t inet_network(const char *cp);
    inet_network()函数的作用是将cp (IPv4数字和点表法中的字符串)转换为适合用作Internet网络地址的主机字节顺序的数字。如果成功,则返回转换后的地址。如果输入无效,则返回-1。

  4. char *inet_ntoa(struct in_addr in);
    inet_ntoa()函数的作用是:将Internet主机地址(以网络字节顺序给出)转换为IPv4点分十进制格式的字符串。字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

  5. inet_pton(int af, const char *src, void *dst)
    该函数将字符串src转换为af地址族中的网络地址结构,然后将该网络地址结构复制到dst。参数af必须是AF_INET或AF_INET6。DST是按网络字节顺序写的。
    Inet_pton()成功时返回1(网络地址已成功转换)。0如果SRC不包含表示指定地址族中有效网络地址的字符串,则返回。如果af不包含有效的地址族,则返回-1并将errno设置为EAFNOSUPPORT。
    与inet_aton(3)和inet_addr(3)不同,inet_pton()支持IPv6地址。另一方面,inet pton()只接受点分十进制表示法的IPv4地址,而inet_aton(3)和inet_addr(3)允许更通用的数字和点表示法(十六进制和八进制数字格式,以及不需要显式写入所有四个字节的格式)。对于同时处理IPv6 ad- 1地址和数字点表示法的IPv4地址的接口,请参见getaddrinfo(3).

  6. const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
    这个函数将af地址族中的网络地址结构src转换为字符串。结果字符串被复制到dst所指向的缓冲区,dst必须是一个非空指针。调用方在参数size中指定此缓冲区中可用的字节数。
    Inet_ntop()扩展了inet_ntoa(3)函数以支持多个地址族,inet_ntoa(3)现在被认为是不推荐的,而支持Inet_ntop()。目前支持的地址族如下:
    在这里插入图片描述
    如果成功,inet_ntop()返回一个指向dst的非空指针。如果有错误,则返回NULL,并设置errno来指示错误。

  7. uint32_t htonl(uint32_t hostlong);
    uint16_t htons(uint16_t hostshort);
    uint32_t ntohl(uint32_t netlong);
    uint16_t ntohs(uint16_t netshort);
    在这里插入图片描述

框架与细节

成员

在这里插入图片描述
成员是一个sockaddr_in结构体,具体见上面介绍。

函数

在这里插入图片描述
主要是构造函数,构造分为sockaddr_in构造和ip地址,端口号构造。网络地址结构的设置与获取,以及网络地址的打印。
在这里插入图片描述
其中主要用到的函数,inet_pton与inet_ntop,将字符串src转换为af地址族中的网络地址结构与将af地址族中的网络地址结构src转换为字符串。htons与ntohs,主机端口号变成网络端口号与网络端口号变成主机端口号。

使用方法

在这里插入图片描述

源码

//InetAddress.h
#pragma once#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>#include "copyable.h"
#include "Log.h"class InetAddress : copyable {
public:InetAddress(uint16_t port = 8000, const char* ip = "127.0.0.1");InetAddress(sockaddr_in addr) {addr_ = addr;}uint16_t toPort() const {return ntohs(addr_.sin_port);}std::string toIp() const;std::string toIpPort() const;sa_family_t family() const {return addr_.sin_family;}sockaddr_in* getSockAddr() { return &addr_; }void setSockAddr(sockaddr_in addr) { addr_ = addr; }void setSockAddr(uint16_t port, const char* ip);
private:struct sockaddr_in addr_;
};//InetAddress.cpp
#include "InetAddress.h"std::string InetAddress::toIpPort() const {return toIp() + " : " + std::to_string(toPort());
}std::string InetAddress::toIp() const {char buf[64] = {0};if (::inet_ntop(addr_.sin_family, &addr_.sin_addr, buf, sizeof buf) == nullptr) {LOG_ERROR("%s--%s--%d--%d : inet_ntop error\n", __FILE__, __FUNCTION__, __LINE__, errno);}return buf;
}InetAddress::InetAddress(uint16_t port, const char* ip) {bzero(&addr_, sizeof addr_);addr_.sin_family = AF_INET;if (::inet_pton(addr_.sin_family, ip, &addr_.sin_addr) != 1) {LOG_FATAL("%s--%s--%d--%d : inet_pton error\n", __FILE__, __FUNCTION__, __LINE__, errno);}addr_.sin_port = htons(port);
}void InetAddress::setSockAddr(uint16_t port, const char* ip) {bzero(&addr_, sizeof addr_);addr_.sin_family = AF_INET;if (::inet_pton(addr_.sin_family, ip, &addr_.sin_addr) != 1) {LOG_FATAL("%s--%s--%d--%d : inet_pton error\n", __FILE__, __FUNCTION__, __LINE__, errno);}addr_.sin_port = htons(port);
}

结尾

以上就是网络地址InetAddress类的相关介绍,以及我在进行项目重写的时候遇到的一些问题,和我自己的一些心得体会。发现写博客真的会记录好多你的成长,而且对于一个好的项目,写博客也是证明你确实有过深度思考,并且在之后面试或者工作时遇到同样的问题能够进行复盘的一种有效的手段。所以,希望uu们也可以像我一样,养成写博客的习惯,逐渐脱离菜鸡队列,向大佬前进!!!加油!!!

也希望我能够完成muduo网络库项目的深度学习与重写,并在功能上能够拓展。也希望在完成这个博客系列之后,能够引导想要学习muduo网络库源码的人,更好地探索这篇美丽繁华的土壤。致敬chenshuo大神!!!

鉴于博主只是一名平平无奇的大三学生,没什么项目经验,所以可能很多东西有所疏漏,如果有大神发现了,还劳烦您在评论区留言,我会努力尝试解决问题!

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

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

相关文章

在矩池云使用微调ChatGLM3-6B教程

今天给大家介绍下如何在矩池云使用ChatGLM3-6B模型。 1 简介 GitHub&#xff1a;https://github.com/THUDM/ChatGLM3 魔搭&#xff1a;https://modelscope.cn/models/ZhipuAI/chatglm3-6b/ ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的新一代对话预训练模型。ChatGLM3…

租房别再傻傻的扯网线了!随身WiFi靠谱品牌推荐,哪个随身WiFi最好用

如果你是租房党&#xff0c;并且预算有限的话&#xff0c;拉网线太麻烦了&#xff0c;价格很贵&#xff0c;需要搬家的时候还要重新扯线&#xff0c;事儿很多。想买一个网速快&#xff0c;便捷的随身WiFi看电影、刷刷抖音、打打游戏&#xff0c;那一定一定要认真看完我这篇文章…

metrics安装异常原因【doesn‘t contain any IP SANs】

1、问题背景 安装好k8s后&#xff0c;安装metrics-server后发现对应的pod一直无法启动。 apiVersion: v1 kind: ServiceAccount metadata:labels:k8s-app: metrics-servername: metrics-servernamespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Cl…

Jasper report InputStream动态生产Logo

第一步&#xff0c;新建一个Parameter 新建一个对象Parameter&#xff0c;类型为java.io.InputStream 第二步&#xff0c;拖拽Image对象 拖拽Image对象&#xff0c;并调整长宽&#xff0c;Image下选择Expression $P{Logo_Blue} 第三步&#xff0c;把图片转换成stream rptHea…

numpy100练习题,包含相应使用函数解释

取自github开源项目&#xff1a;numpy100题 文章目录 1. 导入numpy库并简写为 np (★☆☆)2. 打印numpy的版本和配置说明 (★☆☆)3. 创建一个长度为10的空向量 (★☆☆)4. 如何找到任何一个数组的内存大小&#xff1f; (★☆☆)5. 如何从命令行得到numpy中add函数的说明文档?…

D41|打家劫舍

198.打家劫舍 初始思路&&题解复盘&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i]。 2.确定递推公式 决定dp[i]的因素就是第i房…

Unity 实用方法 合集

Unity 实用方法 合集 Unity 打字机效果2D 坐标旋转计算球面坐标求值平滑移动鼠标位置获取2D屏幕坐标转世界坐标物体朝向目标多物体中心点生成本地图片加载画面线框显示画面线框显示 搭载效果 贝塞尔曲线绘制贝塞尔曲线绘制 搭载效果 网格弯曲网格弯曲 搭载效果 Delaunay 模型生…

安泰ATA-4014高压功率放大器在传感器脉冲涡流检测中的应用

传感器在工程领域起着至关重要的作用&#xff0c;能够实时获取各种物理量的信息。而功率放大器作为传感器信号处理的重要组成部分&#xff0c;广泛应用于各种测量和控制系统中。本文将探讨功率放大器在这一领域的重要性和作用。 首先&#xff0c;了解传感器脉冲涡流检测的基本原…

二、电脑备份

一、电脑备份 解释&#xff1a;window10目前有电脑备份的功能&#xff0c;一般备份C盘(因为系统在这里)&#xff0c;这个功能挺重要的&#xff0c;能够帮你在危难的时候把电脑拉回来&#xff0c;在按照xxxx教程安装驱动&#xff0c;操作注册表&#xff0c;修改C盘里面跟系统有…

亚信安慧AntDB团队引领数据库创新浪潮

湖南亚信安慧科技有限公司&#xff0c;原亚信科技AntDB团队&#xff0c;近日获得信创工委会颁发的创新活跃度荣誉&#xff0c;充分肯定了其在科技创新领域的杰出表现。在当前全球经济下行的大环境中&#xff0c;创新正逐渐成为国家、企业和个人发展的关键因素。亚信安慧作为一家…

AI芯片:神经网络研发加速器、神经网络压缩简化、通用芯片 CPU 加速、专用芯片 GPU 加速

AI芯片&#xff1a; 神经网络研发加速器、神经网络压缩简化、通用芯片 CPU 加速、专用芯片 GPU 加速 神经网络研发加速器神经网络编译器神经网络编译器 神经网络加速与压缩&#xff08;算法层面&#xff09;知识蒸馏低秩分解轻量化网络剪枝量化 通用芯片 CPU 加速x86 加速arm 加…

【Linux】应用与驱动交互及应用间数据交换

一、应用程序与 Linux 驱动交互主要通过以下几种方式&#xff1a; 1. 系统调用接口&#xff08;System Calls&#xff09;: 应用程序可以通过系统调用&#xff0c;如 open(), read(), write(), ioctl(), 等来与设备驱动进行交互。这些调用最终会通过内核转发到相应的驱动函数…

安装ubuntu22.04系统,GPU驱动,cuda,cudnn,python环境,pycharm

需要准备一个u盘&#xff0c;需要格式化&#xff0c;且内存不小于8g 1 下载ubuntu镜像 下载链接&#xff1a; https://cn.ubuntu.com/download/desktop 2下载rufus Rufus - 轻松创建 USB 启动盘Rufus: Create bootable USB drives the easy wayhttps://rufus.ie/zh/ 准备好这…

Abp 创建一个模版demo并运行

Demo效果 &#xff1a;简单的单表crud后台服务。不包含UI 项目类型是模块ABP。生成的结构和 多应用/单应用 有差异。 结合文档以及git的源码分享一下demo的理解 abp文档&#xff1a;API/Auto API Controllers | Documentation Center | ABP.IO 前置准备&#xff1a; Net8 环境…

鹅目标检测数据集VOC格式300张

鹅&#xff0c;一种家禽&#xff0c;以其独特的形态、生活习性和文化象征意义而备受人们喜爱。 鹅属于鸟纲、雁形目、鸭科&#xff0c;是一种大型水禽。它们的身体肥胖&#xff0c;羽毛洁白如雪&#xff0c;嘴部扁平且坚硬&#xff0c;脚部有蹼&#xff0c;适合在水中游动。 …

VBA_NZ系列工具NZ11:VBA光标跟随策略

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…

【vue3中状态管理工具pinia的使用】pinia状态一(state)

1、安装 yarn add pinia//或者//npm install pinia2、在main.js中引入store // 引入piniaimport { createPinia } from piniaconst pinia createPinia()// 使用piniaapp.use(pinia)3、创建一个Store 在项目根目录的 src文件夹 —— 创建store文件夹 —— 创建 index.js 文件 …

MongoDB查找命令find,让数据返回称心如意

业务系统接入数据库后&#xff0c;每天都有大量的数据写入数据库。面对逐日增加的数据&#xff0c;开发人员或数据分析人员&#xff0c;该如何读取数据&#xff0c;怎样设置条件&#xff0c;从数据库中查询数据&#xff1f; 本文基于mongodb的官方文档&#xff0c;整理出find命…

​电脑技巧:​笔记本电脑电流声的原因和解决方案

目录 一、音频设备接口接触不良 二、笔记本电源问题 三、笔记本电脑驱动程序问题 四、音频硬件问题 五、操作系统内部电磁干扰 六、最后总结 大家在日常生活当中&#xff0c;笔记本电脑已经成为我们工作、学习和娱乐的重要工具。但有时我们在使用过程中可能会遇到一个令人…

机器学习中的隐马尔可夫模型及Python实现示例

隐马尔可夫模型&#xff08;HMM&#xff09;是一种统计模型&#xff0c;用于描述观测序列和隐藏状态序列之间的概率关系。它通常用于生成观测值的底层系统或过程未知或隐藏的情况&#xff0c;因此它被称为“隐马尔可夫模型”。 它用于根据生成数据的潜在隐藏过程来预测未来的观…