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

news2024/11/18 20:32:40

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);
}

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

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

相关文章

我用 midjourney 创作的那些好看的图片

下面这些是个人的midjourney v5的关键词&#xff0c;各种类型都有 抽象画 One piece of original artwork from 1998 , in the style of confucian ideology, pop art-inspired collages, recycled material murals, meticulous military scenes, close-up intensity, grocer…

计算机基础面试题 |13.精选计算机基础面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Scikit-Learn线性回归(四)

Scikit-Learn线性回归四:梯度下降 1、梯度下降1.1、梯度下降概述1.2、梯度下降及原理1.3、梯度下降的实现2、梯度下降法求解线性回归的最优解2.1、梯度下降法求解的原理2.2、梯度下降法求解线性回归的最优解2.3、梯度下降法求解线性回归案例(波士顿房价预测)3、Scikit-Learn…

如何提高3D渲染速度

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 1、3D渲染快慢和什么有关&#xff1f; 渲染时间受项目的CPU和项目各类…

SpringDoc注解解析

一、什么是SpringDoc SpringDoc注解的使用&#xff0c;它是基于OpenAPI 3和Swagger 3的现代化解决方案&#xff0c;相较于旧版的Swagger2(SpringFox)&#xff0c;SpringDoc提供了更简洁、更直观的注解方式。 二、SpringDoc的注解分类 2.1 作用于类的注解 1. Tag 用于说明…

ssm基于java web 的QQ村旅游网站的设计+vue论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统旅游信息管理难度大&#xff0c;容错率低&#xff0c;管理…

深度解析分布式算法:构建高效稳定的分布式系统

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

频率域滤波图像复原之逆滤波的python实现——数字图像处理

逆滤波原理 逆滤波是一种在频率域进行的图像复原技术&#xff0c;常用于修复由运动模糊等因素引起的图像退化。具体步骤如下&#xff1a; **频率域表示&#xff1a;**首先&#xff0c;将退化的图像通过傅里叶变换从空间域转换到频率域。这使得图像的频率成分变得明显&#xf…

metaSPAdes,megahit,IDBA-UB:宏基因组装软件安装与使用

metaSPAdes,megahit,IDBA-UB是目前比较主流的宏基因组组装软件 metaSPAdes安装 GitHub - ablab/spades: SPAdes Genome Assembler #3.15.5的预编译版貌似有问题&#xff0c;使用源码安装试试 wget http://cab.spbu.ru/files/release3.15.5/SPAdes-3.15.5.tar.gz tar -xzf SP…

STM32 JLINK SWD调试器手动复位才能烧写的问题

STM32 JLINK SWD调试器手动复位才能烧写的问题 Chapter1 STM32 JLINK SWD调试器手动复位才能烧写的问题 Chapter1 STM32 JLINK SWD调试器手动复位才能烧写的问题 原文链接&#xff1a;https://blog.csdn.net/denghuajing/article/details/121649667 问题 只有手动复位的情况下…

小游戏实战丨基于PyGame的俄罗斯方块小游戏

文章目录 写在前面PyGame五子棋注意事项系列文章写在后面 写在前面 本期内容&#xff1a;基于pygame的俄罗斯方块小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700182 实验环境 python3.11及以上pycharmtkinter PyGame Pygame是一个非常…

优化|PLSA理论与实践

PLSA又称为概率潜在语义分析&#xff0c;是一种利用概率生成模型对文本集合进行话题分析的无监督学习方法。该模型最大的特点是加入了主题这一隐变量&#xff0c;文本生成主题&#xff0c;主题生成单词&#xff0c;从而得到单词-文本共现矩阵。本文将对包含物理学、计算机科学、…

PHP进阶-实现网站的QQ授权登录

授权登录是站点开发常见的应用场景&#xff0c;通过社交媒体一键授权可以跳过注册站点账户的繁琐操作。本文将讲解如何用PHP实现QQ授权登录。首先&#xff0c;我们需要申请QQ互联开发者账号获得APPID和密钥&#xff1b;接着&#xff0c;我们下载QQ官方SDK&#xff1a;PHP SDK v…

分布式数据之复制(Replication)

1.简介 1.1简介——使用复制的目的 在分布式系统中&#xff0c;数据通常需要被分散在多台机器上&#xff0c;主要为了达到以下目的&#xff1a; 扩展性&#xff0c;数据量因读写负载巨大&#xff0c;一台机器无法承载&#xff0c;数据分散在多台机器 上可以有效地进行负载均衡…

【无标题】MySQL8修改非root用户密码

首先查看修改的用户信息&#xff0c;我这里用户名是demo&#xff0c;host是**%** 然后使用alter命令修改密码 这里USER后的参数是第一步里查询得到的user与host的组合。ALTER USER demo% IDENTIFIED WITH mysql_native_password BY 新密码;可能会出现的错误&#xff1a; 如果百…

故障诊断 | 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型(matlab +python)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 故障诊断 | 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型&#xff08;matlab python&#xff09; 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型 特征拼接 python&#xff08;pytorch&#xff09; 基于2D-…

【Unity】 HTFramework框架(四十七)编辑器日志中使用超链接的技巧

更新日期&#xff1a;2024年1月3日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 日志中使用超链接超链接-网络地址超链接-本地地址超链接-项目资源文件超链接-脚本对象 日志中使用超链接 在编辑器控制台Console中的日志是支持富文本的&…

SpringSecurity集成JWT实现后端认证授权保姆级教程-环境搭建篇

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

HTML 使用 ruby 给汉字加拼音

使用 ruby 给汉字加拼音 兼容性 使用 ruby 给汉字加拼音 大家有没有遇到过要给汉字头顶上加拼音的需求? 如果有的话, 你是怎么解决的呢? 如果费尽心思, 那么你可能走了很多弯路, 因为 HTML 原生就有这样的标签来帮我们实现类似的需求. <ruby> ruby 本身是「红宝石」…

详解Keras3.0 Callbacks API : TensorBoard(可视化工具)

TensorBoard TensorBoard是TensorFlow提供的可视化工具。需要安装TensorFlow才能使用此回调。此回调记录TensorBoard的事件&#xff0c;包括&#xff1a;度量汇总图、训练图可视化、重量直方图、采样剖面。 keras.callbacks.TensorBoard(log_dir"logs",histogram_…