TcpSocket类之Open中的同步解析和异步解析

2013年7月2日 由 Creater 留言 »

TcpSocket类之Open解析描述了Open函数

bool TcpSocket::Open(const std::string &host,port_t port)

该函数完成host到ip的转换并且connect到host与port指定的服务器。

#ifdef ENABLE_RESOLVER
	if (!Handler().ResolverEnabled() || Utility::isipv4(host) )
	{
#endif
		ipaddr_t l;
		if (!Utility::u2ip(host,l))
		{
			SetCloseAndDelete();
			return false;
		}
		Ipv4Address ad(l, port);
		Ipv4Address local;
		return Open(ad, local);
#ifdef ENABLE_RESOLVER
	}
	// resolve using async resolver thread
	m_resolver_id = Resolve(host, port);
	return true;
#endif

如果ResolverEnabled没有启动[!Handler().ResolverEnabled()],则使用同步方式来获取地址信息。
如果该string为字符串形式表示的点分十进制IP地址,则并不需要解析就可以直接转换出ip地址。
那么什么时候需要解析呢,那就是你输入别名或者主机名。比如你输入www.baidu.com或者localhost之类。
这也就是为什么会存在这样的语句:

if (!Handler().ResolverEnabled() || Utility::isipv4(host) )

再说一次,host这个string描述的是服务器地址信息,port描述的是服务器端口信息。
但是host可能是ip地址形式,比如127.0.0.1
也可能是名字形式,比如localhost
那么localhost需要解析,而127.0.0.1则可以直接使用u2ip转换成二进制ip地址。

这里需要注意的是,为什么不使用同步的u2ip->gethostbyname或getaddrinfo。
而是使用异步的Reslove线程。

使用异步解析时,调用如下

m_resolver_id = Resolve(host, port);

返回一个m_resolver_id 用来在后边对解析后的结果匹配。

大致调用过程

m_resolver_id = Resolve(host, port);

|
|

int Socket::Resolve(const std::string& host,port_t port)
{
	return Handler().Resolve(this, host, port);
}

|
|

int SocketHandler::Resolve(Socket *p,const std::string& host,port_t port)
{
	// check cache
	ResolvSocket *resolv = new ResolvSocket(*this, p, host, port);
	resolv -> SetId(++m_resolv_id);
	resolv -> SetDeleteByHandler();
	ipaddr_t local;
	Utility::u2ip("127.0.0.1", local);
	if (!resolv -> Open(local, m_resolver_port))
	{
		LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
	}
	Add(resolv);
	m_resolve_q[p -> UniqueIdentifier()] = true;
DEB(	fprintf(stderr, " *** Resolve '%s:%d' id#%d  m_resolve_q size: %d  p: %p\n", host.c_str(), port, resolv -> GetId(), m_resolve_q.size(), p);)
	return resolv -> GetId();
}
int SocketHandler::Resolve(Socket *p,ipaddr_t a)
{
	// check cache
	ResolvSocket *resolv = new ResolvSocket(*this, p, a);
	resolv -> SetId(++m_resolv_id);
	resolv -> SetDeleteByHandler();
	ipaddr_t local;
	Utility::u2ip("127.0.0.1", local);
	if (!resolv -> Open(local, m_resolver_port))
	{
		LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
	}
	Add(resolv);
	m_resolve_q[p -> UniqueIdentifier()] = true;
	return resolv -> GetId();
}

广告位

发表评论

你必须 登陆 方可发表评论.