本文介绍: 以及其他搜索结果,如果没通过SO_LINGER选项改变close默认行为调用close关闭socket时,会关闭两个方向数据流。写方向上,内核尝试发送缓冲区数据发送,之后发送FIN包结束连接,这个过程中,往套接字写入数据都会返回异常;最近使用自研http client发现一个问题,对端在发送响应数据之后立即调用close关闭连接,我这没有调用响应的回调,而是调用到了连接关闭的回调。有问题接收代码如下问题在于recv返回0时,没有处理已经收到数据就直接关闭socket

最近使用自研http client发现一个问题,对端在发送响应数据之后立即调用close关闭连接,我这没有调用响应的回调,而是调用到了连接关闭的回调。对端延迟一会再关闭连接就没问题,用curl访问也是正常的。经过排查是没有正确处理对端关闭导致的。

根据gnu文档以及其他搜索结果,如果没通过SO_LINGER选项改变close默认行为调用close关闭socket时,会关闭两个方向数据流。读方向上,内核会将套接字设置为不可读,任何读操作都会返回异常;写方向上,内核尝试发送缓冲区数据发送,之后发送FIN包结束连接,这个过程中,往套接字写入数据都会返回异常;若对端还发送数据过来,会返回一个RST报文

epoll触发EPOLLIN事件时,表示对应连接上有数据可以读出。tcp连接远端主动关闭连接,也相当于可读事件,因为需要处理发送来的FIN包。

有问题的接收代码如下,问题在于recv返回0时,没有处理已经收到的数据就直接关闭socket。

int tcp_event::handle_read()
{
	octets& read_buf = _ses->get_read_buf();
	int ret_bytes = 0;
	while(true)
	{
		if(read_buf.full())
		{
			_ses->onrecv();
		}
		int bytes_cnt = recv(_fd, read_buf.end(), read_buf.free_space(), 0);
		if(bytes_cnt == 0)
		{
			_ses->close(CLOSE_REASON_ONRECV);
			return -1;
		}
		else if(bytes_cnt != -1)
		{
			ret_bytes += bytes_cnt;
			read_buf.resize(read_buf.size() + bytes_cnt);
		}
		else
		{
			if(errno == EAGAIN || errno == EWOULDBLOCK) break;
			if(errno == EINTR) continue;
			_ses->close(CLOSE_REASON_ONRESET);
			return -1;
		}
	}
	_ses->onrecv();
	return ret_bytes;
}

原文地址:https://blog.csdn.net/liuyuan185442111/article/details/134610811

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_14837.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注