• muduo源码剖析之InetAddress


    InetAddress

    InetAddress 类是 muduo 网络库中的一个重要类,用于表示网络中的 IP 地址和端口号。

    InetAddress 类在 muduo 网络库中被广泛使用,用于表示网络中的通信实体的地址信息,例如服务器地址、客户端地址等。通过 InetAddress 类,我们可以方便地操作 IP 地址和端口号,实现网络通信的功能。

    源码比较简单,已经编写详细注释

    源码剖析

    InetAddress.h

    // Copyright 2010, Shuo Chen.  All rights reserved.
    // http://code.google.com/p/muduo/
    //
    // Use of this source code is governed by a BSD-style license
    // that can be found in the License file.
    
    // Author: Shuo Chen (chenshuo at chenshuo dot com)
    //
    // This is a public header file, it must only include public header files.
    
    #ifndef MUDUO_NET_INETADDRESS_H
    #define MUDUO_NET_INETADDRESS_H
    
    #include "muduo/base/copyable.h"
    #include "muduo/base/StringPiece.h"
    
    #include 
    
    namespace muduo
    {
    namespace net
    {
    namespace sockets
    {
    const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr);
    }
    
    ///
    /// Wrapper of sockaddr_in.
    ///
    /// This is an POD interface class.
    class InetAddress : public muduo::copyable
    {
     public:
      /// Constructs an endpoint with given port number.
      /// Mostly used in TcpServer listening.
      explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false);
    
      /// Constructs an endpoint with given ip and port.
      /// @c ip should be "1.2.3.4"
      InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
    
      /// Constructs an endpoint with given struct @c sockaddr_in
      /// Mostly used when accepting new connections
      explicit InetAddress(const struct sockaddr_in& addr)
        : addr_(addr)
      { }
    
      explicit InetAddress(const struct sockaddr_in6& addr)
        : addr6_(addr)
      { }
      //返回addr_地址成员变量的协议族
      sa_family_t family() const { return addr_.sin_family; }
    
      //获取ip地址的点十分进制的字符串
      string toIp() const;
    
      //获取ip地址和port端口的点十分进制的字符串
      string toIpPort() const;
    
      //获取端口号(本机字节序)
      uint16_t port() const;
    
      // default copy/assignment are Okay
      //返回sockaddr结构体指针
      const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast(&addr6_); }
    
      //设置SockAddr
      void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; }
    
      //获取ip地址(网络字节序)
      uint32_t ipv4NetEndian() const;
    
      //获取端口号(网络字节序)
      uint16_t portNetEndian() const { return addr_.sin_port; }
    
      // resolve hostname to IP address, not changing port or sin_family
      // return true on success.
      // thread safe
      //通过主机名解析出ip地址
      static bool resolve(StringArg hostname, InetAddress* result);
      // static std::vector resolveAll(const char* hostname, uint16_t port = 0);
    
      // set IPv6 ScopeID
      //设置ipv6地址的作用域范围。
      void setScopeId(uint32_t scope_id);
    
     private:
      union
      {
        //ipv4
        struct sockaddr_in addr_;
        //ipv6
        struct sockaddr_in6 addr6_;
      };
    };
    
    }  // namespace net
    }  // namespace muduo
    
    #endif  // MUDUO_NET_INETADDRESS_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    InetAddress.cc

    // Copyright 2010, Shuo Chen.  All rights reserved.
    // http://code.google.com/p/muduo/
    //
    // Use of this source code is governed by a BSD-style license
    // that can be found in the License file.
    
    // Author: Shuo Chen (chenshuo at chenshuo dot com)
    
    #include "muduo/net/InetAddress.h"
    
    #include "muduo/base/Logging.h"
    #include "muduo/net/Endian.h"
    #include "muduo/net/SocketsOps.h"
    
    #include 
    #include 
    
    // INADDR_ANY use (type)value casting.
    #pragma GCC diagnostic ignored "-Wold-style-cast"
    static const in_addr_t kInaddrAny = INADDR_ANY;
    static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
    #pragma GCC diagnostic error "-Wold-style-cast"
    
    //     /* Structure describing an Internet socket address.  */
    //     struct sockaddr_in {
    //         sa_family_t    sin_family; /* address family: AF_INET */
    //         uint16_t       sin_port;   /* port in network byte order */
    //         struct in_addr sin_addr;   /* internet address */
    //     };
    
    //     /* Internet address. */
    //     typedef uint32_t in_addr_t;
    //     struct in_addr {
    //         in_addr_t       s_addr;     /* address in network byte order */
    //     };
    
    //     struct sockaddr_in6 {
    //         sa_family_t     sin6_family;   /* address family: AF_INET6 */
    //         uint16_t        sin6_port;     /* port in network byte order */
    //         uint32_t        sin6_flowinfo; /* IPv6 flow information */
    //         struct in6_addr sin6_addr;     /* IPv6 address */
    //         uint32_t        sin6_scope_id; /* IPv6 scope-id */
    //     };
    
    using namespace muduo;
    using namespace muduo::net;
    
    static_assert(sizeof(InetAddress) == sizeof(struct sockaddr_in6),
                  "InetAddress is same size as sockaddr_in6");
    static_assert(offsetof(sockaddr_in, sin_family) == 0, "sin_family offset 0");
    static_assert(offsetof(sockaddr_in6, sin6_family) == 0, "sin6_family offset 0");
    static_assert(offsetof(sockaddr_in, sin_port) == 2, "sin_port offset 2");
    static_assert(offsetof(sockaddr_in6, sin6_port) == 2, "sin6_port offset 2");
    
    InetAddress::InetAddress(uint16_t portArg, bool loopbackOnly, bool ipv6)
    {
      static_assert(offsetof(InetAddress, addr6_) == 0, "addr6_ offset 0");
      static_assert(offsetof(InetAddress, addr_) == 0, "addr_ offset 0");
      if (ipv6)
      {
        memZero(&addr6_, sizeof addr6_);
        addr6_.sin6_family = AF_INET6;
        in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any;
        addr6_.sin6_addr = ip;
        addr6_.sin6_port = sockets::hostToNetwork16(portArg);
      }
      else
      {
        memZero(&addr_, sizeof addr_);
        addr_.sin_family = AF_INET;
        in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
        addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
        addr_.sin_port = sockets::hostToNetwork16(portArg);
      }
    }
    
    InetAddress::InetAddress(StringArg ip, uint16_t portArg, bool ipv6)
    {
      if (ipv6 || strchr(ip.c_str(), ':'))
      {
        memZero(&addr6_, sizeof addr6_);
        sockets::fromIpPort(ip.c_str(), portArg, &addr6_);
      }
      else
      {
        memZero(&addr_, sizeof addr_);
        sockets::fromIpPort(ip.c_str(), portArg, &addr_);
      }
    }
    
    string InetAddress::toIpPort() const
    {
      char buf[64] = "";
      sockets::toIpPort(buf, sizeof buf, getSockAddr());
      return buf;
    }
    
    string InetAddress::toIp() const
    {
      char buf[64] = "";
      sockets::toIp(buf, sizeof buf, getSockAddr());
      return buf;
    }
    
    uint32_t InetAddress::ipv4NetEndian() const
    {
      assert(family() == AF_INET);
      return addr_.sin_addr.s_addr;
    }
    
    uint16_t InetAddress::port() const
    {
      return sockets::networkToHost16(portNetEndian());
    }
    
    static __thread char t_resolveBuffer[64 * 1024];
    
    bool InetAddress::resolve(StringArg hostname, InetAddress* out)
    {
      assert(out != NULL);
      struct hostent hent;
      struct hostent* he = NULL;
      int herrno = 0;
      memZero(&hent, sizeof(hent));
    
      //通过主机名解析出ip地址
      int ret = gethostbyname_r(hostname.c_str(), &hent, t_resolveBuffer, sizeof t_resolveBuffer, &he, &herrno);
      if (ret == 0 && he != NULL)
      {
        assert(he->h_addrtype == AF_INET && he->h_length == sizeof(uint32_t));
        out->addr_.sin_addr = *reinterpret_cast<struct in_addr*>(he->h_addr);
        return true;
      }
      else
      {
        if (ret)
        {
          LOG_SYSERR << "InetAddress::resolve";
        }
        return false;
      }
    }
    
    void InetAddress::setScopeId(uint32_t scope_id)
    {
      if (family() == AF_INET6)
      {
        addr6_.sin6_scope_id = scope_id;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
  • 相关阅读:
    Kindling-OriginX 在快手 Staging 环境的异常诊断效果分享
    解决线程安全问题&&单例模式
    研发效能认证学员作品:持续集成与持续部署:软件高质量的关键丨IDCF
    【element-ui】form表单动态修改rules校验项
    Kubernetes - 一键安装部署 K8S(附:Kubernetes Dashboard)
    利用西门子低代码实现企业质量管理流程的敏捷性
    2021-03-11 51蛋骗鸡串口中断流水灯回复
    SpringBoot集成Shiro
    【强化学习】policy gradient的一些tips
    【每日一题Day344】LC2512奖励最顶尖的 K 名学生 | 哈希表+排序
  • 原文地址:https://blog.csdn.net/weixin_50448879/article/details/134277878