IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP过程中,网络断开问题解决办法 -> 正文阅读

[网络协议]TCP过程中,网络断开问题解决办法

最近工作过程中,遇到了在TCP建立好连接以后,发送和接收过程中,网络断开引起的socket无法关闭的问题。

ps:TCP的发送和接收都使用的是阻塞模式

一、设置发送和接收的超时时间

最开始想到的解决办法是设置发送和接收的超时时间,这样超时时间到了,发送和接收都会返回,socket就能正常关闭了。但是设置超时时间会引起其他问题。

1、设置发送超时以后,客户端(上位机)会出现,Interrupted system call问题,产生原因是send函数在阻塞模式下,一定要等到有可用空间将send发送的数据拷贝到发送缓冲中,但是超时了,还没发送,就出现Interrupted system call。

2、设置接收超时以后,客户端(上位机)会出现,TCP读取 [WinError 10053] 你的主机中的软件中止了一个已建立的连接问题

二、加大发送缓冲区

上面试验了,发送改为非阻塞行不通,所以还是改为阻塞了。既然是因为发送缓冲区太小了,导致send函数阻塞在等待可用缓冲区上了,那我直接加大发送缓冲区,让send函数能立即返回,这样send就不会阻塞了。

1.设置socke的发送缓冲区大小,实验了不生效


int sendbuf_len = (320 * 1024);

setsockopt(newsockfd, SOL_SOCKET, SO_SNDBUF, &sendbuf_len, sizeof(int));

最后通过直接修改系统的TCP发送缓冲区解决

/proc/sys/net/core/rmem_max        #收缓冲区最大值
/proc/sys/net/core/wmem_max        #发缓冲区最大值
/proc/sys/net/core/rmem_default    #收缓冲区默认值
/proc/sys/net/core/wmen_default    #发缓冲区默认值


1.一次能send的最大数据是发送缓冲区最大值的两倍(x2)

2.默认发送缓冲区最大值默认是(160 * 1024)
所以这里一次能发送的最大数据就是(320 * 1024)


3.观察应用层,发现发送的最大数据大小是 (450 * 1024)
所以这里设置发送缓冲区最大值为 (320 * 1024 = )

echo 327680 > /proc/sys/net/core/wmem_max

三、设置tcp的keepalive属性

接收阻塞的问题还没有解决,最后发现通过设置tcp的keepalive属性能解决网络断开以后,接收阻塞不退出问题。

int keepalive = 1; // 开启keepalive属性

int keepidle = 10; // 如该连接在10秒内没有任何数据往来,则进行探测

int keepinterval = 3; // 探测时发包的时间间隔为3秒

int keepcount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(newsockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));

setsockopt(newsockfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(keepidle));

setsockopt(newsockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval, sizeof(keepinterval));

setsockopt(newsockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount, sizeof(keepcount));

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:42:56  更:2022-07-05 23:43:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 16:19:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码