socket 接收和发送缓冲区
问题产生:
在进行客户端向服务端发送数据时,每次发送一定数量数据后发送端就等不到send函数的返回,导致程序一直卡死在send函数。
通过抓包发现:发送端发送过快而接收端处理速度过慢,导致快速发送一定量数据后wireshark显示发送端发送数据有window full提醒,几次之后接收端会发送zero window消息,发送缓冲区数据无法发出导致堆积满发送缓冲区,从而导致send无法将数据拷贝进发送缓冲区,进而形成send函数无法返回,程序阻塞无法运行。
分析:
recv端表现:在刚开始发送数据时,接收端处于慢启动状态,滑动窗口值越来越大,但是由于接收端不处理接收缓冲区内的数据,其滑动窗口越来越小(因为接收端回应发送端中的win大小表示接受端还能够接受多少数据,发送端下次发送的数据大小不能超过回应中win的大小),最后发送端回应给接受端的ACK中显示的win大小为0,表示接收端不能够再接受数据。
send端表现:发送端一直不能返回,如果接收端一直回应win为0的情况下,发送端的send就会一直不能返回,这种僵局一直持续到接收端的缓冲区数据被处理完成空出足够接收一定量数据的空间。
原因分析:首先需要明白几个事实,阻塞式I/O会一直等待,直达这个操作完成;发送端接受到接收端的回应后才能将发送缓冲区中的数据进行清空。
那么接收端的接收缓冲区满,导致滑动窗口为0,发送端不能发送数据。但是send操作为何不能返回呢?send操作只是将应用缓冲区的数据拷贝到发送缓冲区,但是发送缓冲区的数据并没有完全得到接收端的ACK回应,所以暂时不能将发送缓冲区中的数据丢弃,导致发送缓冲区的被填满,这样应用层中的数据也就不能拷贝到内核发送缓冲区内,也就会一直阻塞在这里,直到可以继续将应用层的数据拷贝到发送缓冲区中,何时触发这个操作呢?等到发送端回应win大于0时才有这样的操作。
遗留问题:
接收端一直在接收数据,将缓冲区数据处理写入本地文件,但是问题产生后程序将会一直阻塞基本未见好转情况。同时抓包数据显示recv端一直有zero window消息,send端一直发送心跳包检测。为什么程序一直卡死,并且接收端缓冲区不见减小?
-->>解答:
接收端使用ET模式,而且每次接收数据buff设置小于发送的buff,导致每次收到ET消息后只会处理部分缓冲区内数据,导致缓冲区数据持续增长直至窗口缩小为0。
至此,发送端不能再发送数据,接收端将不会收到ET信号。从而缓冲区数据将不会减少,窗口一直保持为0的状态。程序死锁,一直hang住。
socket 接收和发送缓冲区的更多相关文章
- 设置socket接收和发送超时的一种方式
Linux环境设置Socket接收和发送超时: 须如下定义:struct timeval timeout = {3,0}; //设置发送超时setsockopt(socket,SOL_SOCKET, ...
- TCP的发送缓冲区和接收缓冲区
TCP协议是作用是用来进行端对端数据传送的,那么就会有发送端和接收端,在操作系统有两个空间即user space和kernal space. 每个Tcp socket连接在内核中都有一个发送缓冲区和接 ...
- Python3的tcp socket接收不定长数据包接收到的数据不全。
Python Socket API参考出处:http://blog.csdn.net/xiangpingli/article/details/47706707 使用socket.recv(pack_l ...
- 【实验室笔记】C#的Socket客户端接收和发送数据
采用socket发送和接收数据的实验中,服务器采用的是网络助手作为模拟服务器端. 客户端程序流程: 应用的命名空间: using System.Net; using System.Net.Socket ...
- 【转】Socket接收字节缓冲区
原创本拉灯 2014年04月16日 10:06:55 标签: socket / 数据包 4448 我们接收Socket字节流数据一般都会定义一个数据包协议( 协议号,长度,内容),由于Socket接收 ...
- 项目总结22:Java UDP Socket数据的发送和接收
项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...
- C#高性能大容量SOCKET并发(三):接收、发送
原文:C#高性能大容量SOCKET并发(三):接收.发送 异步数据接收有可能收到的数据不是一个完整包,或者接收到的数据超过一个包的大小,因此我们需要把接收的数据进行缓存.异步发送我们也需要把每个发送的 ...
- udp协议的数据接收与发送的代码
我想基于lwIP协议中的UDP协议,用单片机做一个服务器,接受电脑的指令然后返回数据.以下是我的代码 /************************************************ ...
- 网络编程基础【day09】:socket接收大数据(五)
本节内容 1.概述 2.socket接收大数据 3.中文字符的坑 一.概述 上篇博客写到了,就是说当服务器发送至客户端的数据,大于客户端设置的数据,则就会把数据服务端发过来的数据剩余数据存在IO缓冲区 ...
随机推荐
- Recurrent Neural Network(3):LSTM Basics and 《Inside Out》
下图是Naive RNN的Recurrent Unit示意图,可以看到,在每个时间点t,Recurrent Unit会输出一个隐藏状态ht,对ht加工提取后将产生t时刻的输出yt.而在下一个时间节点t ...
- Django 无法通过request.POST.get()获取数据的问题
原来是contentType为application/json时,Django不支持request.POST.get(),但可以通过request.body来获取string类型的参数: data = ...
- ThreadLocal和单例对象比较
单例对象: 自始至终只有一个对象 当线程并发,每个线程需要自己独立的资源变量处理不同的业务时,单例对象远远不能满足需求 因此可以采用ThreadLocal模式 : 每个线程有自己独立的资源变量 ...
- [POJ3612] Telephone Wire(暴力dp+剪枝)
[POJ3612] Telephone Wire(暴力dp+剪枝) 题面 有N根电线杆,初始高度为h[i],要给相邻的两根连线.可以选择拔高其中一部分电线杆,把一根电线杆拔高\(\Delta H\)的 ...
- BZOJ 3262(Treap+树状数组)
题面 传送门 分析 分三维考虑 对第一维,直接排序 对第二维和第三维,我们这样考虑 朴素的方法是建k棵Treap,第i棵Treap里存第二维值为k的第三维数值 每次查询一组(a,b,c),只要在1~b ...
- Java 小技巧和在Java避免NullPonintException的最佳方法(翻译)
前几天就g+里面看到有人引用这篇博文.看了一下.受益颇多. 所以翻译过来,希望和大家一起学习.本人英语水平有限,假设有错,请大家指正. 原文地址(须要翻墙):http://ja ...
- Go语言_并发
并发 Go 将并发结构作为核心语言的一部分提供.本节课程通过一些示例介绍并展示了它们的用法. Go 作者组编写,Go-zh 小组翻译. https://tour.go-zh.org/concurren ...
- defer、panic和recover
1. defer(1)defer用于将某个方法或语句推迟到当前函数返回的最后一刻执行,一般用于释放某些已分配的资源.函数返回的最后一刻指的是,return语句更新返回值变量之后,函数返回之前,所以de ...
- SQL server 连接 查询
在sql server中,我们经常能用到连接,今天总结一下连接的基础知识.连接的分类: 交叉连接CROSS JOIN 内连接INNER JOIN 外连接{左外连接LEFT [OUTER] JOIN : ...
- Metasploitable2使用指南
Metasploitable2使用指南 Metasploitable2 虚拟系统是一个特别制作的ubuntu操作系统,本身设计作为安全工具测试和演示常见漏洞攻击.版本2已经可以下载,并且比上一个版本包 ...