socket问题记录

本文章主要记录写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

发送缓冲大小修改没用,读缓冲可以。不明白原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值