本章总结Tars中对文件描述符进行操作时的一些“套路”的做法,偏重异常时候的处理。这些处理方式在任何RPC框架中都是值得考虑的
int iReuseAddr = 1;
//设置
setSockOpt(SO_REUSEADDR, (const void *)&iReuseAddr, sizeof(int), SOL_SOCKET);
int flag = 1;
if(setSockOpt(SO_KEEPALIVE, (char*)&flag, int(sizeof(int)), SOL_SOCKET) == -1)
{
throw TC_Socket_Exception("[TC_Socket::setKeepAlive] error", errno);
}
int flag = 1;
if(setSockOpt(TCP_NODELAY, (char*)&flag, int(sizeof(int)), IPPROTO_TCP) == -1)
{
throw TC_Socket_Exception("[TC_Socket::setTcpNoDelay] error", errno);
}
linger stLinger;
stLinger.l_onoff = 1; //在close socket调用后, 但是还有数据没发送完毕的时候容许逗留
stLinger.l_linger = 0; //容许逗留的时间为0秒
if(setSockOpt(SO_LINGER, (const void *)&stLinger, sizeof(linger), SOL_SOCKET) == -1)
{
throw TC_Socket_Exception("[TC_Socket::setNoCloseWait] error", errno);
}
void TC_Socket::setblock(int fd, bool bBlock)
{
int val = 0;
if ((val = fcntl(fd, F_GETFL, 0)) == -1)
{
throw TC_Socket_Exception("[TC_Socket::setblock] fcntl [F_GETFL] error", errno);
}
if(!bBlock)
{
val |= O_NONBLOCK;
}
else
{
val &= ~O_NONBLOCK;
}
if (fcntl(fd, F_SETFL, val) == -1)
{
throw TC_Socket_Exception("[TC_Socket::setblock] fcntl [F_SETFL] error", errno);
}
}
while ((ifd = ::accept(_sock, pstSockAddr, &iSockLen)) < 0 && errno == EINTR);
if(errno == EAGAIN)
//跳出外层循环accept操作
if (ev.events & EPOLLERR || ev.events & EPOLLHUP)
//把描述符从epoll中删除,同时调用close清理描述符
while(true)
{
char buffer[32 * 1024];
int iBytesReceived = 0;
iBytesReceived = ::read(_sock.getfd(), (void*)buffer, sizeof(buffer));
if (iBytesReceived < 0)
{
if(errno == EAGAIN)
{
//没有数据了
break;
}
else
{
//客户端主动关闭
//把描述符从epoll中删除,同时调用close清理描述符
}
}
else if( iBytesReceived == 0)
{
//把描述符从epoll中删除,同时调用close清理描述符
}
}
int bytes = static_cast<int>(::writev(sock, &buffers[0], cnt));
if (bytes == -1)
{
assert (errno != EINVAL);
if (errno == EAGAIN)
return 0;
//把描述符从epoll中删除,同时调用close清理描述符
}
int bytes = ::send(_sock.getfd(), data, len, 0);
if (bytes == -1)
{
if (EAGAIN == errno)
bytes = 0;
if (EINTR == errno)
bytes = 0; // try ::send later
//把描述符从epoll中删除,同时调用close清理描述符
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。