场景
Thrift框架采用了异常处理机制,因此用户异常断开连接的情况下,当尝试发送数据给用户端的时候,Thrift库会抛出异常,导致进程中断。这种情况是非常正常的,服务器端应该捕获异常的发生,但是不应该异常退出。所以应该当前发送数据失败,直接返回
修改代码如下:
uint32_t TSocket::write_partial(const uint8_t* buf, uint32_t len) {
if (socket_ == -1) {
return -1;
throw TTransportException(TTransportException::NOT_OPEN, "Called write on non-open socket");
}
uint32_t sent = 0;
int flags = 0;
#ifdef MSG_NOSIGNAL
// Note the use of MSG_NOSIGNAL to suppress SIGPIPE errors, instead we
// check for the EPIPE return condition and close the socket in that case
flags |= MSG_NOSIGNAL;
#endif // ifdef MSG_NOSIGNAL
int b = send(socket_, const_cast_sockopt(buf + sent), len - sent, flags);
++g_socket_syscalls;
if (b < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
return 0;
}
// Fail on a send error
int errno_copy = errno;
GlobalOutput.perror("TSocket::write_partial() send() " + getSocketInfo(), errno_copy);
if (errno_copy == EPIPE || errno_copy == ECONNRESET || errno_copy == ENOTCONN) {
//修改的第一个地方,直接返回-1,不抛出异常
close();
return -1;
//throw TTransportException(TTransportException::NOT_OPEN, "write() send()", errno_copy);
}
//修改的第二个地方,直接返回-1,不抛出异常
close();
return -1;
throw TTransportException(TTransportException::UNKNOWN, "write() send()", errno_copy);
}
// Fail on blocked send
if (b == 0) {
throw TTransportException(TTransportException::NOT_OPEN, "Socket send returned 0.");
}
return b;
}
原文地址:http://blog.51cto.com/fengyuzaitu/2071200