阻塞IO下的echo回显实验
我们只关心代码中的业务逻辑和底层阻塞原因
客户端代码
发送数据
std::string message(len, 'S');
int nw = stream->sendAll(message.c_str(), message.size());
printf("sent %d bytes\n", nw);
接受服务端回显的数据
std::vector<char> receive(len);
int nr = stream->receiveAll(receive.data(), receive.size());
printf("received %d bytes\n", nr);
服务端代码
采用thread per connection 模型,每个链接分配一个线程来进行数据回显
InetAddress listenAddr(3007);
Acceptor acceptor(listenAddr);
printf("Accepting... Ctrl-C to exit\n");
int count = 0;
bool nodelay = argc > 1 && strcmp(argv[1], "-D") == 0;
while (true)
{
TcpStreamPtr tcpStream = acceptor.accept();
printf("accepted no. %d client\n", ++count);
if (nodelay)
tcpStream->setTcpNoDelay(true);
// C++11 doesn't allow capturing unique_ptr in lambda, C++14 allows.
std::thread thr([count] (TcpStreamPtr stream) {
printf("thread for no. %d client started.\n", count);
char buf[4096];
int nr = 0;
while ( (nr = stream->receiveSome(buf, sizeof(buf))) > 0)
{
int nw = stream->sendAll(buf, nr);
if (nw < nr)
{
break;
}
}
printf("thread for no. %d client ended.\n", count);
}, std::move(tcpStream));
thr.detach();
发送数据过大时,客户端阻塞的原因分析

在发送数据过大时,客户端会陷入长时间的阻塞状态,发送队列和接受队列的状态如上图,分析代码中的业务逻辑可知,由于客户端在发送完所有数据之后才会接受,在发送的时候将数据放入内核缓冲区,内核缓冲区长度固定,服务端是边读取边发送,所以服务端在向客户端发送回显数据时可能会将发送内核缓冲区填满(此时客户端没有发送完所有元素不会开始读,这样两边都在等待。。。)
解决方式 header + payload 方式进行数据交互
- 从应用层协议解决这个问题
每次发送数据之前进行分包,让接收方准备好对应的内存空间后进行接受,具体应用实例
阻塞IO下的echo回显实验的更多相关文章
- Node.js IO处理输入和回显,以及当今web应用程序的发展史
1.关于Node.js IO处理输入和回显 在Windows终端或者CD中输入 echo 'I must learn about Node.js' 结果将刚刚输入的 echo 'I mus ...
- JS 实现下拉框回显
JS 实现下拉框回显 学习内容: 需求 总结: 学习内容: 需求 用 JS 实现下拉框回显 实现代码 <!DOCTYPE html> <html lang="en" ...
- Layui:select下拉框回显
一..需求场景分析 基于Thymeleaf模板下的layui下选框回显. 二.获得一个Layui标配的下拉框,我们需要在html中填写的内容如下 <div class="layui-f ...
- linux c下输入密码不回显
今天做一个登录程序,需要屏蔽掉密码,于是自己就在网上找资料,找到了一种和linux终端下输入密码方式相同的方法,不显示在终端,具体代码实现如下. #include<stdio.h> #in ...
- vue 运用ElementUI,做select下拉框回显
第一.加载的顺序,应该先加载下拉框要选择的数据,然后在通过编辑查询数据后回显. 第二.要保证select下拉的ID和v-model里边的id保持一致. 第三.elementUI就会自动的将数据回显了. ...
- 关于一个socket在阻塞模式下是否还可以使用的实验
想到一个socket在多线程模式下,是否可以同时使用的问题,比如socket A阻塞在recv,而别的线程用socket A send是否能成功,下面上实验代码 void thread_socket( ...
- linux下输入密码不回显
这几天在做一个登陆的程序,需要将输入的密码屏蔽掉,自己百度,找到了两种方法,先贴下第一种方法, #include<stdio.h> #include<unistd.h> int ...
- thymeleaf单选回显,多选回显,选回显,下拉默认选中第一个
//默认选中第一个<input type ="radio" name="repaymentType" th:each ="repaymentTy ...
- SpEL表达式注入漏洞学习和回显poc研究
目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...
随机推荐
- nyoj-47-过河问题|POJ-1700-Crossing River
http://acm.nyist.net/JudgeOnline/problem.php?pid=47 http://poj.org/problem?id=1700 解题思路:求最少需要多少时间才能都 ...
- javascript基本数据类型问题汇总
isNaN()检测是否是NaN: 比较浮点相等,用绝对值,是否小于某一个阈值 Math.abs(1/3 - (1-2/3))<0.0000001: 字符串多行显示\n,ES6中使用反引号``: ...
- ios 点餐系统
这个程序的主要界面就是一个TabBarController.总共三个标签,第一个是所有的可点的菜,第二个是已点的菜,第三个是可以留言或者查看所有留言. 下面是第一个页面: 右上角的i按钮是添加新菜,每 ...
- shell-code-4-运算符
#1. shell 基本运算符有:算数.关系.布尔.字符串.文件测试运算符#2. 原生bash不支持简单的数学运算,可使用awk和expr(最常用)echo `expr 1 + 2`# 反引号:表达式 ...
- DocView mode 1 -- 手册翻译
文档原文在线地址 * 35 Document Viewing** DocView mode is a major mode for viewing DVI, PostScript (PS), PDF, ...
- Linux下文件打包与解包
打包(.tar): tar -cvf Pro.tar /home/lin/Pro #将/home/lin/Pro文件夹下的所有文件打包成Pro.tar 打解包(.tar.gz) tar -cv ...
- 神经网络的BP推导过程
神经网络的BP推导过程 下面我们从一个简单的例子入手考虑如何从数学上计算代价函数的梯度,考虑如下简单的神经网络,该神经网络有三层神经元,对应的两个权重矩阵,为了计算梯度我们只需要计算两个偏导数即可: ...
- hdu 4764 巴什博弈
Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Percona XtraBackup 2.4新特性之恢复单个表数据
参考文档:https://www.percona.com/doc/percona-xtrabackup/2.4/xtrabackup_bin/restoring_individual_tables.h ...
- 安卓手机 HTML5 手机页面 输入表单被键盘遮挡住了
TML5 手机页面 输入表单被键盘遮挡住了 请问 大神 怎么 js 或者 JQ 判断安卓手机软键盘的键盘隐藏键按下去了? 有使用 uexWindow 方法 能判断到确定键 是 13 但是不知道这个键的 ...