文档章节

TCP粘包/拆包问题处理手段

钟路强
 钟路强
发布于 2016/09/10 18:52
字数 323
阅读 83
收藏 1

TCP以流的方式处理数据,数据发送和接收过程中可能出现拆包或粘包现象,即一次发送的数据分两次接收,或两次发送的数据被一次接收。这在以某种约定协议进行通信的程序设计过程中需要慎重考虑,如果发生粘包或拆包,将使得一次接收的数据报文不完整,所以一般需要将报文设计成定长,或是加入长度字段,按指定的长度来接收数据。按下面这个函数来设计接收程序,可以保证一次读取到所有希望读取的字节数。

/*读取固定字节的数据,数据不够或读取出错时返回-1,成功则返回读取的字节数*/
int read_n(int fd, void *buffer, int count)
{
	int ret;
	int nread, nleft;
	unsigned char *ptr;
	fd_set rset;
	
	ptr = buffer;
	nleft = count;
	while(nleft > 0)
	{
		FD_ZERO(&rset);
		FD_SET(fd, &rset);
		ret = select(fd + 1, &rset, NULL, NULL, NULL);
		if(ret < 0)
		{
			printf("select error\n");
			return -1;
		}
		else
		{
			nread = recv(fd, ptr, nleft, 0);
			if(nread < 0)
			{
				if(errno == EINTR)
				{
					nread = 0;
					printf("EINTR happen when select\n");
				}
				else
				{
					printf("recv error\n");
					return -1;
				}
			}
			else if(nread == 0)
			{
				if((count - nleft) != 0)
				{
					printf("connection closed\n");
					break;
				}
				else
				{
					printf("connection closed errno = %d\n", errno);
					return -1;
				}
			}
			nleft -= nread;
			ptr += nread;
		}
	}
	return count - nleft;
}

© 著作权归作者所有

共有 人打赏支持
钟路强
粉丝 1
博文 7
码字总数 6797
作品 0
杭州
程序员
私信 提问
Netty精粹之TCP粘包拆包问题

粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生这个问题,因此这篇文章只...

Float_Luuu
2016/02/27
8.6K
0
DotNetty 版 开源 mqtt 客户端 (MqttFx)

一、DotNetty背景介绍 某天发现 dotnet 是个好东西,就找了个项目来练练手。于是有了本文的 Mqtt 客户端 (github: MqttFx ) DotNetty是微软的Azure团队,使用C#实现的Netty的版本发布。不但使...

linfx
10/08
0
0
TCP 粘包问题浅析及其解决方案

最近一直在做中间件相关的东西,所以接触到的各种协议比较多,总的来说有TCP,UDP,HTTP等各种网络传输协议,因此楼主想先从协议最基本的TCP粘包问题搞起,把计算机网络这部分基础夯实一下。...

haifeiWu
07/24
0
0
Netty 粘包/拆包应用案例及解决方案分析

熟悉TCP变成的可以知道,无论是客户端还是服务端,但我们读取或者发送消息的时候,都需要考虑TCP底层粘包/拆包机制,下面我们先看一下TCP 粘包/拆包和基础知识,然后模拟一个没有考虑TCP粘包...

Java/Python
08/21
0
0
Netty解决半包(TCP粘包/拆包导致)读写问题

TCP粘包/拆包 TCP是个"流"协议,所谓流,就是没有界限没有分割的一串数据。TCP会根据缓冲区的实际情况进行包划分,一个完整的包可能会拆分成多个包进行发送,也用可能把多个小包封装成一个大...

天冰
2014/06/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL自增属性auto_increment_increment和auto_increment_offset

MySQL的系统变量或会话变量auto_increment_increment(自增步长)和auto_increment_offset(自增偏移量)控制着数据表的自增列ID。 mysql> show tables;Empty set (0.00 sec)mysql> CREATE TA......

野雪球
21分钟前
0
0
OSChina 周三乱弹 —— 有一天考拉麻麻拉肚子了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @瘟神灬念 :分享周汇洋的单曲《Man Srae(曼斯拉之舞)》:美滋滋。。。。 手机党少年们想听歌,请使劲儿戳(这里) 我听了一下 赶紧关了, ...

小小编辑
今天
103
5
oh-my-zsh 自定义

GitHub 地址 基于 oh-my-zsh 的自定义配置,增加了一些个人常用插件与皮肤。 采用的是 git submodule 来维护,包括 oh-my-zsh,之所以这么搞,主要是手头有多台 linux 需要维护, 每台机器、...

郁也风
今天
7
0
Docker安装踩坑:E_FAIL 0x80004005的解决

参考 菜鸟教程--Windows Docker 安装 http://www.runoob.com/docker/windows-docker-install.html 官方文档-Install Docker Toolbox on Windows https://docs.docker.com/toolbox/toolbox_in......

karma123
今天
6
0
js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部