muduo源码剖析之InetAddress

编程入门 行业动态 更新时间:2024-10-24 22:26:54

muduo<a href=https://www.elefans.com/category/jswz/34/1770099.html style=源码剖析之InetAddress"/>

muduo源码剖析之InetAddress

InetAddress

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

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

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

源码剖析

InetAddress.h

// Copyright 2010, Shuo Chen.  All rights reserved.
// /
//
// 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 <netinet/in.h>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 connectionsexplicit 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_); }//设置SockAddrvoid 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<InetAddress> resolveAll(const char* hostname, uint16_t port = 0);// set IPv6 ScopeID//设置ipv6地址的作用域范围。void setScopeId(uint32_t scope_id);private:union{//ipv4struct sockaddr_in addr_;//ipv6struct sockaddr_in6 addr6_;};
};}  // namespace net
}  // namespace muduo#endif  // MUDUO_NET_INETADDRESS_H

InetAddress

// Copyright 2010, Shuo Chen.  All rights reserved.
// /
//
// 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 <netdb.h>
#include <netinet/in.h>// 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;}
}

更多推荐

muduo源码剖析之InetAddress

本文发布于:2023-11-16 02:34:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1611730.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:源码   muduo   InetAddress

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!