处理TCP连包的一小段代码
学习网络编程也有一段时间了,一直听说TCP数据会连包,但一直不知道怎么测试好。最近测试了下:发送方使用对列,将发送的数据存入队列,然后开线程,专门发送。发送多包数据之间不延时。在接收方,他们确实连在一起了。花了点时间,写了一小段代码解决这个问题,其实一共也就4个函数:
#define FIND_NO_HEAD 1024 int MyTcpSock::GetPackageSetedLength(char *pHeader)
{
XX_NETPACKET_HEADER *pNetHeader = (XX_NETPACKET_HEADER *)pHeader; return (sizeof(XX_NETPACKET_HEADER) + pNetHeader->packetsize);
} int MyTcpSock::FindHeaderFlag(char *buf,int len)
{
#define FLAGS_NUM 4 int count = ;
char i=;
unsigned char Flags[FLAGS_NUM] = {XX_FLAG1,XX_FLAG2,XX_FLAG3,XX_FLAG4};
XX_NETPACKET_HEADER *pHeader = (XX_NETPACKET_HEADER *)(buf+count); while(count < len)
{
for(i=;i<FLAGS_NUM;i++)
{
if(pHeader->flag == Flags[i])
{
return ((char *)pHeader - buf);
}
} count ++;
pHeader = (XX_NETPACKET_HEADER *)(buf+count);
} return FIND_NO_HEAD;
} void MyTcpSock::ResolveRecievedData(char *buf,int len)
{
char *pUnreslovedData = (char *)buf; //指向待解析的数据的开始
int iUnreslovedDataLen = len; //待解析的数据的长度
int iHeaderPosition = ; //数据头的位置--相对于待解析的数据的起始位置
int iPackageLen = ; //解析出的命令的数据包长度 while(iUnreslovedDataLen > )
{
iHeaderPosition = FindHeaderFlag(pUnreslovedData,iUnreslovedDataLen);
if(iHeaderPosition == FIND_NO_HEAD)
{
TRACE("Find no Header!\n");
Printf(pUnreslovedData,iUnreslovedDataLen);
return ;
}
iPackageLen = this->GetPackageSetedLength((char *)(pUnreslovedData+iHeaderPosition));
if(iPackageLen > iUnreslovedDataLen)
{
TRACE("Package is not full!\n");
Printf(pUnreslovedData,iUnreslovedDataLen);
return ;
} ResolvePackageCmd((char *)(pUnreslovedData+iHeaderPosition),iPackageLen); pUnreslovedData = pUnreslovedData + iHeaderPosition + iPackageLen; //调整指针
iUnreslovedDataLen = iUnreslovedDataLen - iHeaderPosition - iPackageLen;
}
} void MyTcpSock::ResolvePackageCmd(char *buf,int len)
{
XX_NETPACKET_HEADER *pNetHeader = (XX_NETPACKET_HEADER *)buf; //XXX后面就是命令的解析了
}
以上代码是C++,去掉类就是C。以上代码经过测试,可以解决如下问题:
数据连包的问题。
数据发送丢失,比如有包头却丢失了一些数据。后面解析这些命令时,如果以为数据存在,直接用将会出现不可预知的错误。
命令包格式的设计,基本要遵守CLV的格式,C-code命令,L-Length命令长度,V-Value值。
这里的命令也基本上就是上面的Flag,因为不通命令可能带的值不一样,所以也就必须定义此命令的长度。这在连包处理上非常重要。
处理TCP连包的一小段代码的更多相关文章
- 关于PHP的一小段代码求解如下求解"%2\$s"
<?php$format = "The %2\$s contains %1\$d monkeys";printf($format, 8, "北京");?& ...
- 假设写一段代码引导PC开机这段代码是 ? Here is a tiny "OS" :-D
Hello world -- OS 我找到了华科绍志远博士的相关代码,发现他依据MIT的JOS的boot.S 稍作改动.然后单独剥离出来,能够非常好玩~ 资料下载地址: http://download ...
- Netty TCP粘包/拆包问题《一》
1.使用LineBasedFrameDecoder,StringDecoder解析器进行解决TCP粘包/拆包问题 2.代码搞起: TimeClient:客户端 /* * Copyright 2013- ...
- TCP粘包处理通用框架--C代码
说明:该文紧接上篇博文“ linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现 ”讲来 (1)TCP粘包处理数据结构设计 #define MAX_MSG_LEN 65535 ty ...
- TCP粘"包"问题浅析及解决方案Golang代码实现
一.粘"包"问题简介 在socket网络编程中,都是端到端通信,客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一条连接.在TCP的sock ...
- [置顶] NS2中对TCP数据包和ACK包的TCP Sink类的主要实现代码详尽剖析--吐血放送
NS2中对TCP数据包和ACK包的TCP Sink类的主要实现代码详尽剖析,限于个人水平,如有错误请留言指出! TcpSink类的recv()方法: void TcpSink::recv(Packet ...
- 6行代码解决golang TCP粘包
转自:https://studygolang.com/articles/12483 什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用golang的bufio.Scanner来实现 ...
- TCP数据包的封包和拆包
//该段博文为引用,非原创. 封包和拆包 作者:fengge8ylf 博客:http://blog.csdn.net/fengge8ylf 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就 ...
- (经典)tcp粘包分析
转载自csdn:http://blog.csdn.net/zhangxinrun/article/details/6721495 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问 ...
随机推荐
- 2014·NOIP 新的历程,新的开始
10.12 从9月1号开始奋战,到了今天终于重新把所有普及和提高的复赛题全部AC了.40多天AC130多道想想也是醉了,也许是机房一群大神给予我的压力吧. 想想暑假,整天玩游戏,与此同时,CZL.CY ...
- [BZOJ1572] [Usaco2009 Open]工作安排Job(贪心 + 堆)
传送门 把任务按照d排序 一次加入到堆中,如果当前放不进堆中,并且比堆中最小的大, 就从堆中弹出一个数,再把当前的数放进去 #include <queue> #include <cs ...
- bzoj 5110 Yazid的新生舞会
题目大意: 一个数列,求有多少个区间$[l,r]$满足该区间的众数出现次数大于$\lceil \frac{r-l}{2} \rceil$ 思路: 对于一个区间满足条件的众数明显是唯一的 所以设该数的前 ...
- 《写给大忙人看的Java核心技术》 勘误
先附上十分讨喜的封面.这应该是爱丽丝梦游仙境里的那只兔子吧? 勘误表基于原版勘误表制作 链接 截止日期 2017-02-09 对应<写给大忙人看的Java核心技术>2016年1月第1次印刷 ...
- ORACLE的impdp和expdp命令【登录、创建用户、授权、导入导出】
使用EXPDP和IMPDP时应该注意的事项: EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用, ...
- 使用注解开发springmvc
1.导入jar包 commons-logging-1.2.jar spring-aop-4.3.6.RELEASE.jar spring-beans-4.3.6.RELEASE.jar spring- ...
- 洛谷—— P3375 【模板】KMP字符串匹配
P3375 [模板]KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如 ...
- android 圆形按钮
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...
- Go -- 通过GOTRACEBACK生成程序崩溃后core文件的方法(gcore gdb)
写一个错误的c程序 package dlsym import "testing" func Test_intercept(t *testing.T) { Intercept(& ...
- centos6安装debuginfo
查看内核版本,查找对应的内核rpm文件 [root@localhost ~]#uname -rsp Linux 3.10.0-229.1.2.el7.x86_64 x86_64 去debuginfo. ...