FTP文件管理项目(本地云)项目日报(关于不定长包的测试)

举报
看,未来 发表于 2020/12/29 23:44:45 2020/12/29
【摘要】 第一次弄不定长包,大家都不太熟,网络上又众说纷纭,没有一个完整代码可以参考,所以我们走了不少的弯路。 昨天把解压包模块测试一遍,并进行了修订(主要是队员们很迫切的再问这个模块到底要怎么弄,不然我可能今天还在计划)。 看,这个模块,19号就写好了,一直拖到12号才测。 接下来来看一下对比代码: 关于原先解压包模块的设计图和代码在日报2中:FTP文件管理项目(本地...

第一次弄不定长包,大家都不太熟,网络上又众说纷纭,没有一个完整代码可以参考,所以我们走了不少的弯路。
昨天把解压包模块测试一遍,并进行了修订(主要是队员们很迫切的再问这个模块到底要怎么弄,不然我可能今天还在计划)。

在这里插入图片描述

看,这个模块,19号就写好了,一直拖到12号才测。

接下来来看一下对比代码:

关于原先解压包模块的设计图和代码在日报2中:FTP文件管理项目(本地云)项目日报(二)
但是我要重新做个图了。

旧图:

在这里插入图片描述

新图:

在这里插入图片描述

新旧对比

1、旧图中使用的是两个包对象完成一条服务,但是新包是一个对象,为什么呢?因为之前我一直以为包的body一旦分配内存之后,便固定住了,后来我发现,可以有以下操作:

char *a;
a = new char[10];
sprintf(a,"abcdefg");

a = new char[20];
sprintf(a,"abcdefghijklmn");

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

而上下两块内存是不冲突的,顶多是一点内存碎片,如果严谨一点,那就delete之后再new。
受到启发,我将代码进行修改,在解包时使用一块不算大的内存(包体通常很小,大的是包头),封包的时候再根据实际情况进行封包。

2、解包、封包时包体的偏移量。
之前用定长包的时候,对包的偏移就是sizeof(body),因为那时候body是这样定义的:char body[1024 - sizeof(head) - sizeof(tail)],所以sizeof(body)并没有什么问题,但是现在的body是不定长的,是这样的:char* body; body = new char[sizeof(具体协议包)],那这时候情况就不一样了,没什么特殊情况,指针大小都是4。关于这点,我调试了好一会儿才想起来,为什么数据打印出来会丢哈哈哈,原来就写了四个字节进去。

接着看一下代码修改:

解压包旧代码:

bool PacketBase::pack()
{ Body = new char[Body_Size]; memcpy(m_Data, &this->Head, sizeof(packet_header_t)); memcpy(m_Data + sizeof(packet_header_t), this->Body, sizeof(Body)); //这个Body长度在封包的时候定  memcpy(m_Data + sizeof(packet_header_t) + sizeof(Body), &this->Tail, sizeof(packet_tali_t)); return true;
}

bool PacketBase::unpack()
{ if (Body_Size <= 0) {   //如果数据不足 std::cout << "数据包破损" << std::endl; return false; } Body = new char[Body_Size]; //防止越界可以在这里下手    memcpy(&this->Head, m_Data, sizeof(packet_header_t));   //先将包头读出 memcpy(Body, m_Data + sizeof(packet_header_t), sizeof(Body)); memcpy(&this->Tail, m_Data + sizeof(packet_header_t) + sizeof(Body), sizeof(packet_tali_t)); return true; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

解压包新代码:

bool PacketBase::pack()
{ memcpy(m_Data, &this->Head, sizeof(packet_header_t)); memcpy(m_Data + sizeof(packet_header_t), this->Body, Body_Size); memcpy(m_Data + sizeof(packet_header_t) + Body_Size, &this->Tail, sizeof(packet_tali_t)); return true;
}

bool PacketBase::unpack() { if (Body_Size <= 0) { std::cout << "数据包破损" << std::endl; return false; } Body = new char[Body_Size]; memcpy(&this->Head, m_Data, sizeof(packet_header_t));   //ÏȽ«°üÍ·¶Á³ö memcpy(Body, m_Data + sizeof(packet_header_t), Body_Size); memcpy(&this->Tail, m_Data + sizeof(packet_header_t) + Body_Size, sizeof(packet_tali_t)); return true; 
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

注意加以区分。

具体协议包就代码:

bool PacketCommand1::replyLogin(int state, int dir_id,int fd) { Head.funcId = 0x01; Head.optid = 0x01; Head.fd = fd; Head.usrlenth = sizeof(Body);   //谁开的包谁封回去,所以大小是相对静止了 Head.syn = 0x04; res_login_t* body = (res_login_t*)Body; body->login_ret = state; body->dir_id = dir_id; Tail.pack_tail = 0x05; return this->pack();
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

具体协议包新代码:

bool PacketCommand1::replyLogin(int state, int dir_id,int fd) {
//加了下面这几行 int sz = sizeof(res_login_t); this->setBodySize(sz); this->Body = new char[sz]; Head.funcId = 0x01; Head.optid = 0x01; Head.fd = fd; Head.usrlenth = sz;	//还有这里    Head.syn = 0x04; res_login_t* body = (res_login_t*)Body; body->login_ret = state; body->dir_id = dir_id; Tail.pack_tail = 0x05; return this->pack();
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

然后呢,放一个登陆包的测试代码吧,因为每个包的实现方式都一样:

测试代码:

#include"PacketCommand1.h"
#include<iostream>

using namespace std;

int main()
{
	PacketCommand1* pack1 = new PacketCommand1(); pack1->replyLogin(7, 9, 6);

	pack1->unpack();

	cout << pack1->getHead()->fd << endl;
	res_login_t *body = (res_login_t*)pack1->getBody();
	cout << body->dir_id << " " << body->login_ret << endl;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/106915706

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。