SOCKET 通讯通用设计方法

本文详细介绍了如何使用模板方法设计SOCKET通信协议,包括数据包通用格式定义和通用传输协议定义。数据包由包头(包含起始码、包类型、包序列号和校验和等)和数据部分组成。通用传输协议遵循“一问一答”模式,确保数据安全传输。通过状态机模型管理客户端和服务器的交互,确保数据的完整性和正确性。这种模板化设计能提高开发效率并确保不同版本软件的兼容性。
摘要由CSDN通过智能技术生成

在SOCKET收发数据的过程设计,在日常的开发中会经常遇到,如何提供开发效率,使用模板方式进行开发是比较好的方式。

一、数据包通用格式定义

目的:网络传输的主要任务是将一定长度的数据安全传输到另一端,需要对数据包进行定义。

通用的格式是:包头+数据

包头的格式:起始码+包类型+ 包序列号+ 包CRC + 包长

起始码: 数据的起始,作为数据的同步使用,同时也可以用作协议的版本号来使用,比如V1版本定义的包头如下:

typedef struct packet_header_s

{

      unsigned short startcode;

      unsigned short  packet_type;

      unsigned int packet_index;

      unsigned int packet_crc;

      unsigned int      packet_len;

 }PACKET_HEADER_S;

 

可以定义STARTCODE = 0x5548, 下一个版本的定义有可能是这样的

 

typedef struct packet_header_s

{

      unsigned short startcode;

      unsigned char  packet_type;

      unsigned char    packet_section;

 

      unsigned int packet_crc;

      unsigned int      packet_len;

}PACKET_HEADER_S;

定义STARTCODE = 0XF048

这样通过STARTCODE的定义,软件就可以做到兼容,保证不同的版本软件前向兼容

 

包类型:对数据包进行区分,通过不同的包类型去对应不同的自定义协议,比较好的一种方式,也可以是拆包解包的标示,通过包类型对应真实数据的数据格式;

 

包序列号:传输的数据有可能很长,一般是采用分片的方式进行传输,包序列号可以认为是数据分段传输的标识。同时适用于多SOCKET进行数据传输,包的传输有可能是乱序的,通过序列号进行数据分辨;

 

包CRC:对数据进行校验,验证传输的正确性。

 

包长:此定义后面的数据的长度

 

二、通用传输协议定义

通常的做法是采用“一问一答”的方式,即发送,对方回应。对方超时没有回应,重复发。当SOCKET连接后,CLIENT首先发命令包,SERVER收到命令包,准备接收环境,回应是否准备好,CLIENT发送数据,SERVER回应接收情况,CLIENT根据回应包,决定是否传输下一个包,还是重新传输上一个包,重复上述过程,直到所有的数据都发送完成,CLIENT 发送下一个命令包,进行新一轮的数据传输。

 

不同的命令其实就是协议状态的迁移,回应是对命令的回应,同样影响协议状态的迁移,在定义协议的状态时,同时是使用这样的模型。

 

CLIENT、SERVER端需要记录的内容:

数据传输总长度

已经传输的长度

协议状态

 

对应SERVER端还需要记录多个SOCKET的情况

每一个SOCKET的状态

 

举例说明:

文件同步协议定义

typedef struct ptl_syncinfo_s

{

      int status;

      int  last_msgcmd;

     

      ssize_t  totalsize;

      ssize_t actsize;

      ssize_t  lastsize;

      ssize_t blocksize;

 

     

      int  buffer_len;

     

      int  filehd;

      char filename[MAX_FILEPATH_LEN];

      char buffer[MAX_BUFFER];

     

 

}PTL_SYNCINFO_S;

 

协议状态

typedef enum

{

      PTLSTATUS_MASTER_IDLE,

      PTLSTATUS_MASTER_ANSWER,

      PTLSTATUS_MASTER_PRORECEIVE,

      PTLSTATUS_MASTER_RECEIVE,

      PTLSTATUS_MASTER_RECEIVEOK,

     

}PROTOCAL_MASTER_E;

 

typedef enum

{

      PTLSTATUS_SLAVE_IDLE,

      PTLSTATUS_SLAVE_SERVICE,

      PTLSTATUS_SLAVE_REQUEST,

      PTLSTATUS_SLAVE_PROSEND,

      PTLSTATUS_SLAVE_SEND,

      PTLSTATUS_SLAVE_SENDOK,

     

}PROTOCAL_SLAVE_E;

 

命令字

typedef enum

{

      FILESYNC_CMD_S_M_DATA_REQUEST = 0x01,

      FILESYNC_CMD_M_S_DATA_ANSWER,

      FILESYNC_CMD_S_M_SIZE_INFORM,

      FILESYNC_CMD_M_S_SIZE_ANSWER,

      FILESYNC_CMD_S_M_BLOCK_SEND,

      FILESYNC_CMD_M_S_BLOCK_ANSWER,

      FILESYNC_CMD_S_M_PROC_BREAK,

      FILESYNC_CMD_M_S_PROC_BREAKOK,

          

}PTL_FILESYNC_CMD_E;

int PTL_Gossip_Master(SOCKET_MSG_S *msginfo, int index)
{

    int socket_status;
    int ret, num, len;

    PTL_SYNCINFO_S *pinfo;

    if (NULL == msginfo)
        return(-1);

    if (index >= SOCK_MAX || index <0)
        return(-1);
    

    pinfo = &g_syncinfo[index];
        
    socket_status = pinfo->status;


    switch(socket_status)
    {
        case PTLSTATUS_MASTER_IDLE:
            
            if (msginfo->msg_cmd == SOCKCMD_RECEIVE)
            {      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值