【Muduo源码剖析笔记】 网络库之InetAddress
作为sockaddr_in的wrapper。sockaddr_in是socket的专用地址结构体,保存的信息包括地址族、端口号、地址结构体。
// /* 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 */
// };
InetAddress
包含一个Union数据成员,为一个sockaddr_in和一个sockaddr_in6的变量。
共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false)
会根据bool类型值,判断使用的是ipv6还是ipv4,以ipv4举例。
首先将addr_的内容置为0,将地址族设置为AF_INET。
如果loopbackonly,就把ip设置为kInaddrLoopback。否则就设置为kInaddrAny。
INADDR_ANY
转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思。
比如一台电脑有3块网卡,分别连接三个网络,那么这台电脑就有3个ip地址了,如果某个应用程序需要监听某个端口,那他要监听哪个网卡地址的端口呢?
如果绑定某个具体的ip地址,你只能监听你所设置的ip地址所在的网卡的端口,其它两块网卡无法监听端口,如果我需要三个网卡都监听,那就需要绑定3个ip,也就等于需要管理3个套接字进行数据交换,这样岂不是很繁琐?
所以出现INADDR_ANY,你只需绑定INADDR_ANY,管理一个套接字就行,不管数据是从哪个网卡过来的,只要是绑定的端口号过来的数据,都可以接收到。
INADDR_LOOPBACK, 也就是绑定地址LOOPBAC, 往往是127.0.0.1, 只能收到127.0.0.1上面的连接请求
接下来把ip地址从主机端转换成网络字节序。
把端口号转换成网络字节序。
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false)
指定ip地址和端口号,调用fromIpPort构建sockaddr。
default copy/assignment are Okay
还有两个拷贝构造函数,参数分别为sockaddr_in类型和sockaddr_in6类型。
InetAddress::toIpPort()
实际
sockets::toIpPort(buf, sizeof buf, getSockAddr());
socketops中的这个,将地址信息输出放在buf中。返回buf。但是返回类型是string,会使用这个buf构建一个新的buf。
InetAddress::toIp() const同理。
uint32_t InetAddress::ipv4NetEndian() const
返回地址,以网络字节序。
bool InetAddress::resolve(StringArg hostname, InetAddress* out)
hostent是C语言标准库函数gethostbyname的返回值,gethostbyname是用来解析域名的重要函数,在程序的网络应用中经常需要将域名转换为IP地址,然后建立Socket与服务器进行数据交互。
struct hostent
{
char *h_name; //正式主机名
char **h_aliases; //主机别名
int h_addrtype; //主机IP地址类型:IPV4-AF_INET
int h_length; //主机IP地址字节长度,对于IPv4是四字节,即32位
char **h_addr_list; //主机的IP地址列表
};
hostent *host = gethostbyname("www.baidu.com");
int gethostbyname_r (const char *name,struct hostent *ret, char *buf, size_t buflen,struct hostent **result, int *h_errnop);
buffer是由__thread关键字描述的。