设置文件描述符为NonBlock和CloseOnExec
void setNonBlockAndCloseOnExec(int sockfd)
{
// non-block
int flags = ::fcntl(sockfd, F_GETFL, 0);
flags |= O_NONBLOCK;
int ret = ::fcntl(sockfd, F_SETFL, flags);
// close-on-exec
flags = ::fcntl(sockfd, F_GETFL, 0);
flags |= FD_CLOEXEC;
ret = ::fcntl(sockfd, F_SETFD, flags);
(void)ret;
}
创建非阻塞且设置了close-on-exec套接字的两种方法
int sockfd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);
int sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setNonBlockAndCloseOnExec(sockfd);
一般指定listen函数的第二个参数值为SOMAXCONN
::listen(sockfd, SOMAXCONN);
获取套接字发生的错误
int getSocketError(int sockfd)
{
int optval;
socklen_t optlen = static_cast<socklen_t>(sizeof optval);
if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
{
return errno;
}
else
{
return optval;
}
}
accept一个套接字并设置为non-block和close-on-exec的两种方法
sockaddr_in peeraddr;
bzero(&peeraddr, sizeof peeraddr);
socklen_t addrlen = static_cast<socklen_t>(sizeof peeraddr);
int connfd = ::accept(sockfd, (sockaddr*)&peeraddr, &addrlen);
setNonBlockAndCloseOnExec(connfd);
sockaddr_in peeraddr;
bzero(&peeraddr, sizeof peeraddr);
int connfd = ::accept4(sockfd, (sockaddr*)&peeraddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
网友评论