linux服务器开发问题(tcp粘包)

recv的返回值

a. 成功执行时,返回接收到的字节数。另一端已关闭则返回0。

b. 失败返回-1,errno被设为以下的某个值
EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
EBADF:sock不是有效的描述词
ECONNREFUSE:远程主机阻绝网络连接
EFAULT:内存空间访问出错
EINTR:操作被信号中断
EINVAL:参数无效
ENOMEM:内存不足
ENOTCONN:与面向连接关联的套接字尚未被连接上
ENOTSOCK:sock索引的不是套接字

c. 当返回值是0时,为正常关闭连接;

数据发送过快问题

在使用非阻塞套接字的时候

服务器处理部分:

while(1)
{
	recv();
	if(ret==0)
	{
		close();
	}
	if(ret<0)
	{	
		if(errno==EAGAIN)
		{
		add_mod();
		}
	}
	else
	{
		sleep(5);
	}
	cout<<buf<<endl;
}

客户端:

send();
send();
send()

客户端到服务器的传输过程

这里用的是流式套接字:流式套接字的概念就是,数据会像水一样流动,当我们数据流太快,数据就会像水一样连接到一起,而不是像沙子一样,一颗一颗地分开;
在这里插入图片描述

客户端向服务器连续发送数据

当数据发送速度过快,会出现粘包;原因,流式套接字,数据发送过快,服务器套接字读缓冲区的数据未能及时通过recv取出,导致数据粘粘到一起;

比如:客户端连续发送数据,服务器的正在sleep,那么在网络正常的情况下,数据是被接收的(除非客户端写套接字缓冲区,或读套接字缓冲区已经满了),但是接收的数据是在套接字读缓冲区的。如果下一次通过recv接收的数据,如果服务器buf足够大,那么会将服务器在sleep期间的所有数据全部通过接收;

这里有个问题需要注意;\0这个字符;如果你想将接收到的数据打印显示;一定要注虽然数据粘合到一起;如果直接打印字符串会无法显示后面的数据;

原因如下:
如果从套接字缓冲区的通过recv接收到数据是:hello \0 world\0;
使用cout<<buf<<endl;
打印结果是 hello
而不是hello world;

粘包如何处理:
让服务器和客户端buf大小一致;
或则说在服务器设置固定大小的buf;每次recv只从缓冲区取指定大小的数据;

总结:recv和send只是一个数据传输的接口;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值