久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

一個簡單的SOCKET程序的數據包結構和封解包函數

作者:佚名   來源:本站原創   點擊數:  更新時間:2013年12月17日   【字體:

練習寫套接字通信程序時候寫的一段代碼,本來想寫個聊天室但寫來寫去進度卡在界面上接節下來都是通信部分的代碼
因為只是試驗用所以都是用C寫的,等界面部分完工后會用類來封裝一下
因為本人E文很爛所以變量和函數的命名是具有中國特色的,求理解.不過我注釋的很詳細了
謹以此文紀念我那坑爹的編程自學生涯......................
 
#include "stdio.h"
#include <windows.h>
//////////////////////////////數據包接構//////////////////////////////////////
//數據包類型CTOS為客戶端使用的數據包,STOC為服務端使用的數據包
#define CTOS 1
#define STOC 2
//數據包存儲管道每個包最大為2000字節,其中數據載荷為最大1800字節,其余留著擴展數據包頭
struct SJGD {
 BYTE sjgd[2000];  //數據緩沖區
 DWORD sjcd;    //數據長度
};
//數據包頭大小為8字節
struct MSG_TOU {
     DWORD lxid; //數據包類型
     DWORD sxid;  //數據包順序標號
  DWORD sjbcd; //數據包長度
};
//服務端-》客戶端包
struct MSG_STOC {
    DWORD cmd;    //命令標識
 DWORD sjbcd; //整個MSG_STOC數據包緩沖區的長度
 BYTE shuju[1000];   //附加數據緩沖區
};
//客戶端-》服務器包
struct MSG_CTOS {
    DWORD cmd;    //命令標識
 DWORD sjbcd; //整個MSG_CTOS數據包緩沖區的長度
 BYTE shuju[1800]; //附加數據緩沖區
};
//共用體
 union MSG_DATA {
      struct MSG_STOC msg_stoc;
   struct MSG_CTOS msg_ctos;
    };
//完整數據包
struct SJB {
 struct MSG_TOU tou; //數據包頭
 union MSG_DATA data;  //數據緩沖區
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//封包函數第一個參數為數據包類型,第二個為命令標識,這是數據包的重點遠控命令會轉換成數字在這里傳輸
//第三個為數據包順序標號,第四個參數為附加數據緩沖區,第五個參數為打包數據緩沖區
//作用是把數據填充成一個標準的遠控數據包為下面的發包做準備
int Fengbao(DWORD lxid,DWORD cmd,DWORD sxid,struct SJGD*sjgd,struct SJB*sjb)
{
 sjb->tou.lxid=lxid;  //填充數據包類型
 sjb->tou.sxid=sxid;  //填充數據包順序標號
 if(lxid==CTOS)
 {
  sjb->data.msg_ctos.cmd=cmd;  //填充命令標識
  MoveMemory(sjb->data.msg_ctos.shuju,sjgd->sjgd,sjgd->sjcd);  //填充附加數據
  sjb->data.msg_ctos.sjbcd=sjgd->sjcd;  //填充整個附加數據緩沖區的長度
 }
 if(lxid==STOC)
 {
  sjb->data.msg_stoc.cmd=cmd; //填充命令標識
        MoveMemory(sjb->data.msg_stoc.shuju,sjgd->sjgd,sjgd->sjcd);  //填充附加數據
  sjb->data.msg_stoc.sjbcd=sjgd->sjcd;  //填充整個附加數據緩沖區的長度
 }
 sjb->tou.sjbcd=20+sjgd->sjcd;   //填充數據包長度
 if((lxid!=CTOS)&&(lxid!=STOC)) return 0;
 return 1;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
//發包函數第一個參數為待發數據包,第二個參數為數據管道緩沖區
//作用是把一個標準數據包以二進制的形式發送到數據管道緩沖區
int Fabao(struct SJB*sjb,struct SJGD*sjgd)
{
 MoveMemory(sjgd->sjgd,&sjb->tou.lxid,4); //填充數據包類型
    MoveMemory(sjgd->sjgd+4,&sjb->tou.sxid,4);//填充數據包順序標號
 if(sjb->tou.lxid==CTOS)
 {
        MoveMemory(sjgd->sjgd+8,&sjb->tou.sjbcd,4); //填充數據包長度
        MoveMemory(sjgd->sjgd+12,&sjb->data.msg_ctos.cmd,4);//填充命令標識
        MoveMemory(sjgd->sjgd+16,&sjb->data.msg_ctos.sjbcd,4);//填充整個附加數據緩沖區的長度    
        MoveMemory(sjgd->sjgd+20,sjb->data.msg_ctos.shuju,sjb->data.msg_ctos.sjbcd); //填充附加數據
        sjgd->sjcd=sjb->tou.sjbcd; //更新數據管道長度數據
     return 1;
 }
 if(sjb->tou.lxid==STOC)
 {
        MoveMemory(sjgd->sjgd+8,&sjb->tou.sjbcd,4);//填充數據包長度
        MoveMemory(sjgd->sjgd+12,&sjb->data.msg_stoc.cmd,4);//填充命令標識
        MoveMemory(sjgd->sjgd+16,&sjb->data.msg_stoc.sjbcd,4);//填充整個附加數據緩沖區的長度
        MoveMemory(sjgd->sjgd+20,sjb->data.msg_ctos.shuju,sjb->data.msg_stoc.sjbcd); //填充附加數據
        sjgd->sjcd=sjb->tou.sjbcd; //更新數據管道長度數據
     return 1;
 }
 return 0;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//函數作用是直接從內存讀取一個4字節的整數,為下面的解包做準備
int hex_int(char c)    //從內存讀取一個1字節的整數
{
 if((c>='A')&&(c<='F'))
 {
 return (int)(c-'A'+10);
 }
 if((c>='0')&&(c<='9'))
 {
 return (int)(c-'0');
 }
 return 0;
}
DWORD hex_dw(BYTE*hex)   //從內存讀取一個4節的整數
{
 DWORD D=0;
    char x[2];
    sprintf(x,"%.2X",hex[0]);
 D+=hex_int(x[1]);
 D+=hex_int(x[0])*16;
    sprintf(x,"%.2X",hex[1]);
 D+=hex_int(x[1])*16*16;
 D+=hex_int(x[0])*16*16*16;
    sprintf(x,"%.2X",hex[2]);
 D+=hex_int(x[1])*16*16*16*16;
 D+=hex_int(x[0])*16*16*16*16*16;
    sprintf(x,"%.2X",hex[3]);
 D+=hex_int(x[1])*16*16*16*16*16*16;
 D+=hex_int(x[0])*16*16*16*16*16*16*16;
 return D;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
//解包函數第一個參數是待解包的數據管道緩沖區,第二個參數為解包數據存儲結構
//函數作用是把數據管道中的數據解封為一個標準的遠控數據包,用以控制程序流程
int Jiebao(struct SJGD*sjgd,struct SJB*sjb)
{
 sjb->tou.lxid=hex_dw(sjgd->sjgd);   //解封數據包類型
 sjb->tou.sxid=hex_dw(sjgd->sjgd+4);  //解封數據包順序標號
    sjb->tou.sjbcd=hex_dw(sjgd->sjgd+8); //解封數據包長度
 if(sjb->tou.lxid==CTOS)
 {
  sjb->data.msg_ctos.cmd=hex_dw(sjgd->sjgd+12);  //解封命令標識
  sjb->data.msg_ctos.sjbcd=hex_dw(sjgd->sjgd+16); //解封整個附加數據緩沖區的長度
  MoveMemory(sjb->data.msg_ctos.shuju,sjgd->sjgd+20,sjb->data.msg_ctos.sjbcd); //解封附加數據
  return 1;
 }
 if(sjb->tou.lxid==STOC)
 {
        sjb->data.msg_stoc.cmd=hex_dw(sjgd->sjgd+12);  //解封命令標識
  sjb->data.msg_stoc.sjbcd=hex_dw(sjgd->sjgd+16); //解封整個附加數據緩沖區的長度
  MoveMemory(sjb->data.msg_stoc.shuju,sjgd->sjgd+20,sjb->data.msg_ctos.sjbcd); //解封附加數據
  return 1;
 }
 return 0;
}
////////////////////////////////////////////////////////////////////////////////////////

這篇是服務器端的收發線程函數 http://m.zg4o1577.cn/mcu/2611.html

關閉窗口

相關文章

主站蜘蛛池模板: 精品理论片 | 欧美成人精品一区二区三区 | 久热精品视频在线观看 | 亚洲一区二区在线 | 国产精品尤物 | 中文字幕超清在线观看 | 亚洲精品网站在线观看 | 国产精品久久久久久久久借妻 | 中文字幕在线视频播放 | 欧美福利一区二区 | 久久久久久久99 | 91精品视频在线 | 国产成人精品免费视频 | 国产麻豆一区二区三区 | 夜夜操夜夜爽 | 日韩av在线免费看 | 国产日韩欧美 | 黄色三级视频网站 | 精品视频在线播放 | 成人欧美一区二区三区白人 | 一级片欧美 | 成人区精品一区二区婷婷 | 亚洲成人一区二区 | 五月开心激情网 | 国产精品久久久久久久成人午夜 | 激情网站在线观看 | 国产又粗又猛又爽又黄 | 在线国产小视频 | 国产精品一级二级 | 亚洲免费视频一区 | 欧美一级黄色录像 | 久久久久久久91 | 欧美激情啪啪 | 中国第一毛片 | 久久久久久99精品久久久 | 亚洲美女一区 | 红桃av在线| 久久一区二区视频 | 欧美日韩免费在线观看 | 成人在线视频免费观看 | 国产亚洲区|