ACL_VSTREAM *acl_vstream_accept_ex(ACL_VSTREAM *listen_stream, ACL_VSTREAM *client_stream, char *addr, int size) { const char *myname = "acl_vstream_accept_ex"; ACL_SOCKET connfd = ACL_SOCKET_INVALID; ACL_SOCKET servfd = ACL_VSTREAM_SOCK(listen_stream); char buf[256]; if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_INET)) { #ifdef WIN32 if (!(listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_IOCP)) connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf)); else if (listen_stream->iocp_sock == ACL_SOCKET_INVALID) return NULL; else { int ret; connfd = listen_stream->iocp_sock; listen_stream->iocp_sock = ACL_SOCKET_INVALID; /* iocp 方式下,需调用下面过程以允许调用 * getpeername/getsockname */ ret = setsockopt(connfd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&servfd, sizeof(servfd)); buf[0] = 0; if (ret != SOCKET_ERROR) acl_getpeername(connfd, buf, sizeof(buf)); } #else connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf)); #endif if (connfd != ACL_SOCKET_INVALID && addr != NULL && size > 0) ACL_SAFE_STRNCPY(addr, buf, size); #ifdef ACL_UNIX } else if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_UNIX)) { connfd = acl_unix_accept(servfd); if (acl_getpeername(connfd, buf, sizeof(buf)) < 0) buf[0] = 0; if (addr) ACL_SAFE_STRNCPY(addr, buf, size); #endif } else acl_msg_fatal("%s(%d)->%s: invalid listen stream(%d)", __FILE__, __LINE__, myname, listen_stream->flag); if (connfd == ACL_SOCKET_INVALID) return NULL; if (client_stream != NULL) { acl_vstream_reset(client_stream); ACL_VSTREAM_SET_SOCK(client_stream, connfd); } else { client_stream = acl_vstream_fdopen(connfd, ACL_VSTREAM_FLAG_RW, (int) listen_stream->read_buf_len, listen_stream->rw_timeout, ACL_VSTREAM_TYPE_SOCK); /* 让 client_stream 的 context 成员继承 listen_stream 的 * context 成员变量. */ client_stream->context = listen_stream->context; } if (client_stream == NULL) return NULL; acl_vstream_set_peer(client_stream, buf); return client_stream; }
ACL_SOCKET acl_inet_accept(ACL_SOCKET listen_fd) { return acl_inet_accept_ex(listen_fd, NULL, 0); }