const Address* SocketChannel::GetLocalAddress()
{
	if (NULL == m_localAddr)
	{
		try
		{
			//			SocketHostAddress local = getHostAddress(m_fd);
			//			NEW(m_localAddr, SocketHostAddress(local));

			SocketInetAddress inet = get_socket_inet_address(m_fd);
			if (inet.IsUnix())
			{
				SocketUnixAddress local = get_unix_address(inet);
				NEW(m_localAddr, SocketUnixAddress(local));
			} else
			{
				SocketHostAddress local = get_host_address(inet);
				NEW(m_localAddr, SocketHostAddress(local));
			}
		} catch (...)
		{

		}
	}
	return m_localAddr;
}
const Address* SocketChannel::GetRemoteAddress()
{
	if (NULL == m_remoteAddr)
	{
		try
		{

			SocketInetAddress inet = get_remote_inet_address(m_fd);
			if (inet.IsUnix())
			{
				SocketUnixAddress remote = get_unix_address(inet);
				NEW(m_remoteAddr, SocketUnixAddress(remote));
			} else
			{
				SocketHostAddress remote = get_host_address(inet);
				NEW(m_remoteAddr, SocketHostAddress(remote));
			}

		} catch (...)
		{

		}
	}
	return m_remoteAddr;
}
Exemple #3
0
bool SocketChannel::DoBind(Address* local)
{
    if (NULL == local)
    {
        return false;
    }
    SocketInetAddress addr;
    if (InstanceOf<SocketHostAddress>(local).OK)
    {
        SocketHostAddress* host_addr = static_cast<SocketHostAddress*>(local);
        addr = get_inet_address(host_addr->GetHost(), host_addr->GetPort());
    }
    else if (InstanceOf<SocketInetAddress>(local).OK)
    {
        SocketInetAddress* inet_addr = static_cast<SocketInetAddress*>(local);
        addr = (*inet_addr);
    }
    else if (InstanceOf<SocketUnixAddress>(local).OK)
    {
        SocketUnixAddress* unix_addr = (SocketUnixAddress*) local;
        unlink(unix_addr->GetPath().c_str()); // in case it already exists
        addr = get_inet_address(*unix_addr);
    }
    else
    {
        return false;
    }
    if (addr.IsUnix())
    {
        struct sockaddr_un* pun = (struct sockaddr_un*) &(addr.GetRawSockAddr());
        DEBUG_LOG("Bind on %s", pun->sun_path);
    }
    int fd = GetSocketFD(addr.GetDomain());
    if (0 == ::bind(fd, &(addr.GetRawSockAddr()), addr.GetRawSockAddrSize()))
    {
        return true;
    }
    int e = errno;
    ERROR_LOG("Failed to bind address for reason:%s", strerror(e));
    return false;
}
bool ServerSocketChannel::DoBind(Address* local)
{
	if (m_fd > 0)
	{
		return true;
	}
	int on = 1;
	SocketInetAddress addr;
	if (InstanceOf<SocketHostAddress>(local).OK)
	{
		SocketHostAddress* host_addr = (SocketHostAddress*) local;
		addr = get_inet_address(host_addr->GetHost(), host_addr->GetPort());
	} else if (InstanceOf<SocketInetAddress>(local).OK)
	{
		SocketInetAddress* inet_addr = (SocketInetAddress*) local;
		addr = (*inet_addr);
	} else if (InstanceOf<SocketUnixAddress>(local).OK)
	{
		SocketUnixAddress* unix_addr = (SocketUnixAddress*) local;
		int ret = unlink(unix_addr->GetPath().c_str()); // in case it already exists
		if (ret == -1)
		{
			int e = errno;
			ERROR_LOG(
					"unlink %s failed:%s", unix_addr->GetPath().c_str(), strerror(e));
		}
		addr = get_inet_address(*unix_addr);
	} else
	{
		return false;
	}
	int family = addr.GetRawSockAddr().sa_family;
	int fd = ::socket(family, SOCK_STREAM, 0);
	if (fd < 0)
	{
		return false;
	}

	if (make_fd_nonblocking(fd) < 0)
	{
		::close(fd);
		return false;
	}
	if (!addr.IsUnix())
	{
		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
		{
			::close(fd);
			return false;
		}
	} else
	{
		struct sockaddr_un* pun = (struct sockaddr_un*) &(addr.GetRawSockAddr());
		DEBUG_LOG("Bind on %s", pun->sun_path);
//		int nZero = 0;
//		setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &nZero, sizeof(nZero));
//		setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &nZero, sizeof(int));

	}
	//setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*) &on, sizeof(on));
	if (::bind(fd, (struct sockaddr*) &(addr.GetRawSockAddr()),
			addr.GetRawSockAddrSize()) == -1)
	{
		int e = errno;
		ERROR_LOG("Failed to bind address for reason:%s", strerror(e));
		::close(fd);
		return false;
	}
	if (::listen(fd, 511) == -1)
	{ /* the magic 511 constant is from nginx */
		int e = errno;
		ERROR_LOG("Failed to listen for reason:%s", strerror(e));
		::close(fd);
		return false;
	}
	if (aeCreateFileEvent(GetService().GetRawEventLoop(), fd, AE_READABLE,
			Channel::IOEventCallback, this) == AE_ERR)
	{
		::close(fd);
		return false;
	}
	m_fd = fd;
	return true;
}