当前位置:网站首页>socket问题记录
socket问题记录
2022-06-25 06:43:00 【qq_42863961】
本文章主要记录写socket代码时问题。
recv(size)大于缓冲区size会发生什么
这个问题是作者想要发送大文件,但传的很慢,于是提高缓冲区大小,虽然驴不对嘴,但是我照他的想了想,那应该跟正常没啥区别,这个问题就类似于缓冲区的数据为10,你应用里size为100,那接收的不就是10嘛。
如下代码
char msgbuffer[100];
int size;
if((size = recv(sock, msgbuffer, sizeof(msgbuffer), 0)) < 0){
//将缓冲区数据读到msgbuffer中
cout << "读取错误!错误原因 errno:" << errno << endl;
close(sock);
return 0;
}
else if(size == 0){
cout << "读端已关闭" << endl;
close(sock);
return 0;
}
else
cout << "读取成功:" << msgbuffer << endl << "读取字节:" << size << endl;
设置阙值
读阙值可以设置,写不可以,不知为什么
这个是由于网上文章写读写阙值分别为1和2048,但我查了下,都是1,且读阙值可以修改,写阙值不可以。
int val;
socklen_t valLen = sizeof(int);
cout << "套接字读缓冲" << endl;
getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, &valLen);
cout << "默认大小:" << val << endl;
getsockopt(sock, SOL_SOCKET, SO_RCVLOWAT, &val, &valLen);
cout << "默认水位:" << val << endl;
cout << "套接字写缓冲" << endl;
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, &valLen);
cout << "默认大小:" << val << endl;
getsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &val, &valLen);
cout << "默认水位:" << val << endl;
val = 1000;
setsockopt(sock, SOL_SOCKET, SO_RCVLOWAT, &val, sizeof(val));
getsockopt(sock, SOL_SOCKET, SO_RCVLOWAT, &val, &valLen);
cout << "读水位修改为:" << val << endl;
val = 1000;
setsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val));
getsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &val, &valLen);
cout << "写水位修改为:" << val << endl;
会发现写水位为1且不能修改。
读写和修改缓冲区大小
当读端数据>读端缓冲
当写端数据>写端缓冲,会发生什么。
当读端数据 > 读端缓冲
并不会发生什么。读端数据其实就是对端的发送数据。连接的时候发送端会根据读端缓冲区大小设置发送窗口,因此不会溢出。如下代码
//修改读端大小为最小:读端大小最小为2304
val = 1;
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof(int));
getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, &valLen);
cout << "读端大小 :" << val << endl;
//假设对端发送大于2304数据。设为20000
//recv 从缓冲区读
char msgbuffer[1000000];
int size;
int sum = 0;
while(true){
size = recv(sock, msgbuffer, sizeof(msgbuffer), 0);
cout << "读字节:" << size << endl;
sum += size;
if(sum == 20000){
cout << "读总和:" << sum << endl;
return 0;
}
}

我们会发现缓冲区的数据并不会超过缓冲区大小。
//将上边代码msgbuffer修改为100
char msgbuffer[100];

可以看到只读100。这是因为msgbuffer为100,但这并不代表缓冲只有100的数据。
当写端数据 > 写端缓冲
rwqrq
rqwrqw
//修改写端大小为最小:写端大小最小为4608
val = 1;
setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof(int));
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, &valLen);
cout << "写端大小 :" << val << endl;
//假设对端发送大于2304数据。设为20000
//写入
char msgbuffer[20000];
int size;
size = send(sock, msgbuffer, sizeof(msgbuffer), 0);
cout << "写入字节:" << size << endl;
send(sock, msgbuffer, 1000000, 0); 要写100w
recv(sock, msgbuffer, 1000000, 0);要读100w
分别考虑两个事情
1.100w和缓冲区的空间
2.100w和缓冲区的数量
100w < 空间
写成功
100w = 空间
写成功
100w > 空间
写失败,返回写入的数量。
100w < 数量
读成功
100w = 数量
读成功
100w > 数量
读失败,返回读取的数量。
换句话说
当要写的>写入的,说明缓冲区空间<要写的且只有那么多
当要读的>读取的,说明缓冲区数量<要读的且只有那么多
recv(sock, msgbuffer, 1000000, 0);要读100w
返回 < 100w : 读缓冲有 < 100w的数据
返回 = 100w : 读缓冲有>=100w的数据
返回 > 100w : 不可能返回 > 100w
发送缓冲大小修改没用,读缓冲可以。不明白原因。
边栏推荐
猜你喜欢

产品经理专业知识50篇(四)-从问题到能力提升:AMDGF模型工具

One "stone" and two "birds", PCA can effectively improve the dilemma of missing some ground points under the airborne lidar forest

【深度学习 轻量型backbone】2022 EdgeViTs CVPR

NPM install reports an error: gyp err! configure error

剑指 Offer II 027. 回文链表

一次弄清楚 Handler 可能导致的内存泄漏和解决办法

The fourth floor is originally the fourth floor. Let's have a look

Ubuntu18下登录mysql 5.7设置root密码

差点被这波Handler 面试连环炮带走~

Technology blog | how to communicate using SSE
随机推荐
1742. 盒子中小球的最大数量
Atlas conference vulnerability analysis collection
如何用svn新建属于自己的分支
How to select lead-free and lead-free tin spraying for PCB? 2021-11-16
【深度学习 轻量型backbone】2022 EdgeViTs CVPR
Modular programming of oled12864 display controlled by single chip microcomputer
Sword finger offer II 027 Palindrome linked list
DNS协议及其DNS完整的查询过程
Anaconda navigator启动慢的一个解决方法
Manufacturing process of PCB 2021-10-11
传统的IO存在什么问题?为什么引入零拷贝的?
用函数的递归来解决几道有趣的题
Do you know why the PCB produces tin beads? 2021-09-30
力扣76题,最小覆盖字串
opencv最小值滤波(不局限于图像)
php入门基础记录
Three Siemens fire-fighting hosts fc18 are equipped with can optical transceiver for optical fiber redundant ring network networking test
神经网络与深度学习-3- 机器学习简单示例-PyTorch
TCP与UDP
Modular programming of wireless transmission module nRF905 controlled by single chip microcomputer