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缓冲区 ...
随机推荐
- [LeetCode] 421. Maximum XOR of Two Numbers in an Array(位操作)
传送门 Description Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Fin ...
- Spring学习(一)--简化Java开发,认识Spring
一.传统Java开发弊端 在传统的开发之中,任何一个有实际意义的应用都会由两个或更多的类所组成,这些类之间相互协调来完成特定的业务逻辑,按照传统的做法,每个对象负责管理与自己相互协作的对象(即他所依赖 ...
- ExcelVBA 操作putty
Private Sub login(ip As String, userName As String, password As String) Dim TaskID As Long '设置进程id p ...
- Struts2+Ajax实现数据交互
1.导入jar包 struts核心包: json需要的包: 2.配置web.xml <filter> <filter-name>struts2</filter-name& ...
- mysql 主从复制 (2)
今天说一下MySQL的主从复制如何做到! 准备工作: 1.两个虚拟机:我这里用的是CentOS5.5,IP地址分别是192.168.1.101 和192.168.1.105: 101做主服务器,105 ...
- 【JMeter4.0】二、JMeter4.0安装与配置
二.安装配置JMeter jmeter是一个纯java工具,因此,JDK必不可少,现在最新版的jmeter是4.0,建议使用1.8及以上的JDK安装配置JDK,如没有,请见:[JMeter4.0]一. ...
- ASE "黄金点游戏"
问题定义 黄金点游戏是源于经济学家Richar Thaler构思的在1997年伦敦金融时报进行了一次公开竞猜活动.MSRA-ASE课程的第一次结对编程中,我们写了一个AI Bot来与大家玩儿这个游戏. ...
- SpringMVC表单或Json中日期字符串与JavaBean的Date类型的转换
SpringMVC表单或Json中日期字符串与JavaBean的Date类型的转换 场景一:表单中的日期字符串和JavaBean的Date类型的转换 在使用SpringMVC的时候,经常会遇到表单中的 ...
- shell本地变量和环境变量的对比
- 脚本_备份mysql
#!bin/bash#功能:备份mysql数据 #作者:liusingbon#定义变量 user(数据库用户名),passwd(数据库密码),date(备份的时间标签)#dbname(需要备份的数据库 ...