封包和解包简介_马鸿凯_新浪博客

在网上找了好久,差不多多是纯理论的,或者是c++ 或者Java的 自己写

 想看概念的去这里:

原创:黏贴请说明出处

http://www.roboby.com/linux_socket_how_to_clear_receive_buffer.html

http://www.cnblogs.com/khler/archive/2011/05/16/2047362.html

http://www.cnblogs.com/my_life/articles/5363527.html


寻找的参考文档: 看着确实难受 自己改下备注

发送方封包

PACKAGE_HEAD pPackageHead; //PACKAGE_HEAD 包头结构体   除了结构体也可以是别的类型以及大小

char PackageHead[1024]; 

int headLen = sizeof(PACKAGE_HEAD);        // 结构体头部的长度

int packgeContextLen = strlen(packageContext); //发送的数据的长度

pPackageHead->nDataLen = packgeContextLen;   //自己定义的包的大小

 

char *packge = (char*)malloc(headLen + packgeContextLen); //包的内存分配

memset(packge, 0, headLen + packgeContextLen);       // 清空

char *packgeCpy = (char*)memcpy(packge, (char*)&pPackageHead, headLen);  //拷贝包头里面的数据

packgeCpy += headLen;


//拷贝包内容里面的数据

packge = (char*)memcpy(packgeCpy, (char*)&packageContext, packgeContextLen);

 

int ret = 0;

ret = send(m_hSocket, packge, headLen + packgeContextLen, 0); //发送包的内容

if (ret == SOCKET_ERROR || ret == 0)

{

  return ret;

}

//   有上面的解释下面的应该可以看懂了

接收方解包

char PackageHead[1024];   

char PackageContext[1024*20];

 

int len;

PACKAGE_HEAD *pPackageHead; //PACKAGE_HEAD 包头结构体

while( m_bClose == false )

{

  memset(PackageHead, 0, sizeof(PACKAGE_HEAD));

len = ReceiveSize(m_TcpSock, (char*)PackageHead,

sizeof(PACKAGE_HEAD)); //接收包头

 

  if( len == SOCKET_ERROR )

  {

  break;

  }

  if(len == 0)

  {

  break;

  }

  pPackageHead = (PACKAGE_HEAD *)PackageHead;

  memset(PackageContext,0,sizeof(PackageContext));

  if(pPackageHead->nDataLen>0) //根据包头中的数据长度,接收数据

  {

  len = ReceiveSize(m_TcpSock,     (char*)PackageContext,pPackageHead->nDataLen);

  }

}

 

 

接收指定长度的数据函数

 

//接收指定长度的数据

int ReceiveSize(SOCKET m_hSocket, char* strData, int gLen)

{

  if(strData == NULL)

  return ERR_BADPARAM;

  char *p = strData;

  int len = gLen;

  int ret = 0;

  int returnlen = 0;

  while( len > 0)

  {

  ret = recv( m_hSocket, p+(iLen-len), iLen-returnlen, 0);

  if (ret == SOCKET_ERROR || ret == 0)

  {

  return ret;

  }

 

  len -= ret;

  returnlen += ret;

  }

 

  return returnlen;

}


// 然后下面是自己写的 包定义解包封包 

// 头文件

。。。。。

#define NAME_LEN 256      //linux max file name

#define TYPE char

// pack define 

#pragma pack(push,1)

typedef struct packTCP

{

TYPE dataLen;

char data[NAME_LEN]; 

}PACK;

 

#pragma pack(pop)

// 包很简单dataLen 就是包头 只是个char类型当然可以自己改为结构体

// 至于版本号以及校验时间之类的传输的东西暂时不需要



// 封包  自己写的一个函数 列出服务器指定目录下的文件  传输到 客户端

  int do_ls(char *path,const int sock_fd)

 

{

       int reG = 0;

DIR *dir;

struct dirent *ptr;

char base[COMMAND_LINE];

if( (dir=opendir(path)) == NULL )

{

perror("ser: Open dir error---do_ls\n");

exit(EXIT_FAILURE);

}

while( (ptr = readdir(dir)) != NULL )

{

if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..")==0)

{

continue;

}

else if( ptr->d_type == 8 || ptr->d_type == 10)

{

   sleep(1);


PACK pack;

TYPE packHead = 0;


// pack head len

int packHeadLen = sizeof(packHead);


memset(pack.data,'\0',NAME_LEN);

//  pack.data

memcpy(pack.data,path,strlen(path));

strncat(pack.data,"/",1);

   strncat(pack.data,ptr->d_name,strlen(ptr->d_name));

 

// pack data len

packHead  =  strlen(path) + 1 + strlen(ptr->d_name);


char *pPack = (char *)malloc(packHeadLen + packHead) ;

memset(pPack,'\0',packHeadLen + packHead);

 

// copy pack head

char *pPackCp = (char *)strncpy(pPack,(char *)&packHead,packHeadLen);

// copy pack data

       pPack =  (char *) strncat ( pPackCp,(char *)&(pack.data),packHead );  

reG = 0;

reG = send(sock_fd,pPack,packHeadLen+packHead,0);

if( -1 == reG )

{

perror("ser: send fail\n");

exit(EXIT_FAILURE);

}

printf("%d ",pPack[0]);

printf("%s\n",pPack+1);

free(pPack);

pPack = NULL;

}

else if( ptr->d_type == 4 )

{


memset(base,'\0',sizeof(base));

strncpy(base,path,strlen(path));

strcat(base,"/");

strcat(base,ptr->d_name);

do_ls(base,sock_fd);

}

}

return 4;

 

}

/// 解包

客户端接收来自服务器的东西进行解包

int do_sevr_ls(char *path, const int sock_fd)

{

int reG = 0;

printf("\ncli: serverPath :\n\n");

 

TYPE  *pPackHead;

PACK pack;

while(1)

{

memset(pPackHead,0,sizeof(int));

char *p =(char *) pPackHead;

int pPackHeadLen = sizeof(TYPE);

int packLen = sizeof(PACK);


int recvHead = 0;

 

// recv pack head

recvHead = recv(sock_fd,p+pPackHeadLen,pPackHeadLen,0);

if(recvHead == -1)

{

perror("cli: recv fail----do_sevr_ls\n");

exit(EXIT_FAILURE);

}

 

        reG = 2;

reG = strcmp(p+pPackHeadLen ,"#");

if( 0 == reG )

{

break;

}

memset(pack.data,0,sizeof(pack.data));

int recvData = 0;

recvData = recv(sock_fd,(char *)(pack.data),pack.dataLen,0);

printf("%s\n",pack.data);


}

printf("\n\n");


return 1;

 

}

// 很简单的解包和封包 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma_Hong_Kai

微信 2936729162

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值