处理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缓冲区设置的问 ...
随机推荐
- BZOJ 3130 [Sdoi2013]费用流 ——网络流
[题目分析] 很容易想到,可以把P放在流量最大的边上的时候最优. 所以二分网络流,判断什么时候可以达到最大流. 流量不一定是整数,所以需要实数二分,整数是会WA的. [代码] #include < ...
- 洛谷P3759 - [TJOI2017]不勤劳的图书管理员
Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...
- springmvc简单的xml文件配置步骤
1.配置web.xml的servlet标签,在此标签中配置服务器配置文件 2.配置web.xml的servlet-mapping标签 3.配置application.xml的自动扫描包的位置 4.配置 ...
- Linux(11):期中架构(3)--- SSH远程管理服务 & ansible 批量管理服务
SSH远程管理服务 1. 远程管理服务知识介绍 # 1.1 SSH远程登录服务介绍说明 SSH是Secure Shell Protocol的简写,由 IETF 网络工作小组(Network Worki ...
- uva 10870 递推关系矩阵快速幂模
Recurrences Input: standard input Output: standard output Consider recurrent functions of the follow ...
- javaweb学习总结(八)——HttpServletResponse对象(二)(转)
(每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedI ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)
题意:N个点M条边的无向图,q次询问保留图中编号在[l,r]的边的时候图中的联通块个数. 询问加密,强制在线 n,m,q<=200000 题意:RYZ作业 以下转载自hzwer http://h ...
- SSD S.M.A.R.T
经过多年HDD硬盘厂商的完善,S.M.A.R.T已经形成了一些标准,但对于SSD来说,大多数S.M.A.R.T都是自定义的,以至于每个厂商所提供的参数并不一致,但大体都会参考HDD S.M.A.R.T ...
- C# 读写bat文件
读: var batFile = "D:\\test.bat"; if (File.Exists(batFile)) { using (var sr = new StreamRea ...
- 【postgresql】postgresql中的between and以及日期的使用
在postgresql中的between and操作符作用类似于,是包含边界的 a BETWEEN x AND y 等效于 a >= x AND a <= y 在postgresql中比较 ...