設置文件描述符為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;
}
創(chuàng)建非阻塞且設置了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函數(shù)的第二個參數(shù)值為SOMAXCONN
::listen(sockfd, SOMAXCONN);
獲取套接字發(fā)生的錯誤
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);