Exemplo n.º 1
0
bool server_socket::open(const char* addr)
{
#ifndef ACL_WINDOWS
	if (strchr(addr, '/') != NULL)
	{
		fd_ = acl_unix_listen(addr, backlog_, block_
			? ACL_BLOCKING : ACL_NON_BLOCKING);
		unix_sock_ = true;
		ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_));
	}
	else
#endif
		fd_ = acl_inet_listen(addr, backlog_, block_
			? ACL_BLOCKING : ACL_NON_BLOCKING);

	if (fd_ == ACL_SOCKET_INVALID)
	{
		logger_error("listen %s error %s", addr, last_serror());
		unix_sock_ = false;
		ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_));
		return false;
	}

	if (unix_sock_)
		return true;

	// 之所以再用 getsockname 重新获得一些监听地址,主要是为了应对当输入的 addr 
	// 为 ip:0 的情形,即当给定的地址中的端口为 0 时要求操作系统自动分配一个端口号
	if (acl_getsockname(fd_, addr_, sizeof(addr_)) < 0)
	{
		logger_error("getsockname error: %s", acl_last_serror());
		ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_));
	}
	return true;
}
Exemplo n.º 2
0
ACL_VSTREAM *acl_vstream_listen_ex(const char *addr, int qlen,
	int block_mode, int io_bufsize, int io_timeout)
{
	const char *myname = "acl_vstream_listen_ex";
	ACL_SOCKET  listenfd;
	struct sockaddr_in local;
	ACL_VSTREAM *listen_stream;
	int   len;

	if (addr == 0 || *addr == 0 || qlen <= 0)
	{
		acl_msg_error("%s: input invalid", myname);
		return NULL;
	}

#ifdef	ACL_UNIX
	/* this maybe unix addr, such as '/home/test/listen.sock' */
	if (strchr(addr, '/') != NULL) {
		listenfd = acl_unix_listen(addr, qlen, 0);
		if (listenfd == ACL_SOCKET_INVALID)
			return NULL;
		acl_non_blocking(listenfd, block_mode);
		listen_stream = acl_vstream_fdopen(listenfd,
			ACL_VSTREAM_FLAG_RW, io_bufsize,
			io_timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX);

		if (listen_stream == NULL) {
			acl_socket_close(listenfd);
			acl_msg_error("%s: open vstream error, addr(%s)",
				myname, addr);
			return NULL;
		}

		acl_vstream_set_local(listen_stream, addr);

		sprintf(listen_stream->errbuf, "+OK");
		return (listen_stream);
	}
#endif
	/* addr such as '192.168.0.1:80' */
	listenfd = acl_inet_listen(addr, qlen, block_mode);
	if (listenfd == ACL_SOCKET_INVALID) {
		acl_msg_error("%s: listen addr(%s) error(%s)",
			myname, addr, acl_last_serror());
		return NULL;
	}
	listen_stream = acl_vstream_fdopen(listenfd,
		ACL_VSTREAM_FLAG_RW, io_bufsize,
		io_timeout, ACL_VSTREAM_TYPE_LISTEN_INET);
	if (listen_stream == NULL) {
		acl_socket_close(listenfd);
		acl_msg_error("%s: open vstream error addr(%s)", myname, addr);
		return NULL;
	}

	memset(&local, 0, sizeof(local));
	len = (int) sizeof(struct sockaddr);
	if (getsockname(listenfd, (struct sockaddr*) &local,
		(socklen_t *) &len) < 0)
	{
		acl_msg_warn("%s: getsockname error(%s) for sock(%d)",
			myname, acl_last_serror(), listenfd);
		acl_vstream_set_local(listen_stream, addr);
	} else {
		char  ip[32], buf[64];
		int   port;

		acl_inet_ntoa(local.sin_addr, ip, sizeof(ip));
		port = ntohs(local.sin_port);
		snprintf(buf, sizeof(buf), "%s:%d", ip, port);
		acl_vstream_set_local(listen_stream, buf);
	}

	sprintf(listen_stream->errbuf, "+OK");
	return listen_stream;
}