学习网络编程也有一段时间了,一直听说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连包的一小段代码的更多相关文章

  1. 关于PHP的一小段代码求解如下求解"%2\$s"

    <?php$format = "The %2\$s contains %1\$d monkeys";printf($format, 8, "北京");?& ...

  2. 假设写一段代码引导PC开机这段代码是 ? Here is a tiny &quot;OS&quot; :-D

    Hello world -- OS 我找到了华科绍志远博士的相关代码,发现他依据MIT的JOS的boot.S 稍作改动.然后单独剥离出来,能够非常好玩~ 资料下载地址: http://download ...

  3. Netty TCP粘包/拆包问题《一》

    1.使用LineBasedFrameDecoder,StringDecoder解析器进行解决TCP粘包/拆包问题 2.代码搞起: TimeClient:客户端 /* * Copyright 2013- ...

  4. TCP粘包处理通用框架--C代码

    说明:该文紧接上篇博文“ linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现 ”讲来 (1)TCP粘包处理数据结构设计 #define MAX_MSG_LEN 65535 ty ...

  5. TCP粘"包"问题浅析及解决方案Golang代码实现

    一.粘"包"问题简介 在socket网络编程中,都是端到端通信,客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一条连接.在TCP的sock ...

  6. [置顶] NS2中对TCP数据包和ACK包的TCP Sink类的主要实现代码详尽剖析--吐血放送

    NS2中对TCP数据包和ACK包的TCP Sink类的主要实现代码详尽剖析,限于个人水平,如有错误请留言指出! TcpSink类的recv()方法: void TcpSink::recv(Packet ...

  7. 6行代码解决golang TCP粘包

    转自:https://studygolang.com/articles/12483 什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用golang的bufio.Scanner来实现 ...

  8. TCP数据包的封包和拆包

    //该段博文为引用,非原创. 封包和拆包 作者:fengge8ylf  博客:http://blog.csdn.net/fengge8ylf 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就 ...

  9. (经典)tcp粘包分析

    转载自csdn:http://blog.csdn.net/zhangxinrun/article/details/6721495 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问 ...

随机推荐

  1. hdfs api读写文写件个人练习

    看下hdfs的读写原理,主要是打开FileSystem,获得InputStream or OutputStream: 那么主要用到的FileSystem类是一个实现了文件系统的抽象类,继承来自org. ...

  2. P1651 塔 (动态规划)

    题目描述 小明很喜欢摆积木,现在他正在玩的积木是由N个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块.每个木块只能用一次,也可以不用 ...

  3. wsgi 简介

    原文博客地址 http://blog.csdn.net/on_1y/article/details/18803563

  4. java连oracle

    下载连接驱动 安装完oracle之后 D:\app\Administrator\product\11.2.0\dbhome_1\jdbc\lib 目录下拷贝 支持jdk1.6以上 From.java ...

  5. 教妹学 Java:大有可为的集合

    00.故事的起源 “二哥,上一篇<泛型>的反响效果怎么样啊?”三妹对她提议的<教妹学 Java>专栏很是关心. “有人评论说,‘二哥你敲代码都敲出幻想了啊.’” “呵呵,这句话 ...

  6. Atcoder 3857 Median Sum

    Problem Statement You are given N integers A1, A2, ..., AN. Consider the sums of all non-empty subse ...

  7. Java8 本地DateTime API

    原文:http://www.yiibai.com/java8/java8_localdateapi.html 使用Java8,新的日期时间API引入覆盖旧的日期时间API的以下缺点. 非线程安全 - ...

  8. 空暇时候思考2(&#39;\0&#39;等价于数字0还是字符0)

    /********************************************************************** * * Copyright (c)2015,WK Stu ...

  9. C/C++动态二维数组的内存分配和释放

    C语言: 1 //二维数组动态数组分配和释放 //数组指针的内存分配和释放 //方法一 char (*a)[N];//指向数组的指针 a = (char (*)[N])malloc(sizeof(ch ...

  10. 【数据库摘要】6_Sql_Inner_Join

    INNER JOIN 操作符 INNER JOIN keyword在表中存在至少一个匹配时返回行. SQL INNER JOIN 语法 SELECT column_name(s) FROM table ...