zoukankan      html  css  js  c++  java
  • 数据传输 -- 字符串报文

    1. 字符串报文分类: 固定长度字符串报文,  固定分隔符字符串报文。

    2. 字符串报文组包

    3. 字符串报文解析

    字符串报文结构体:

    typedef struct STRRESVARstu
    {
        int nAmount;  //数据域总数
        int nFlag;    //报文类型 0定长域  1分割域
        int *filedlen;	//每个数据域的长度
        int nCompartlen;	//分割符号的长度	
        char szCompart[10];	//分隔符符串
        char **filedaddr;	//指向每个数据域首地址的指针
    } STRRESVAR;


     

    4. 示例一

    #include <iostream>
    #include <string.h>
    #include <assert.h>
    #include <stdlib.h>
    using namespace std;
    
    #define STRSTR 0
    #define STRINT 1
    #define STRDOUBLE 2
    
    typedef struct STRRESVARstu  //字符串报文结构体
    {
        int nAmount;
        int nFlag;
        int *filedlen;
        int nCompartlen;
        char szCompart[10];
        char **filedaddr;
    } STRRESVAR;
    typedef STRRESVAR * PSTRRESVAR;
    
    int strrespre(char *buf, PSTRRESVAR pStrstu)  //解析报文,报文先存储在buf中, pStrstu 为报文结构指针
    {
        int i = 0, j = 0;
        char *p1, *p2;
        assert(buf != NULL && pStrstu != NULL && pStrstu->filedlen != NULL);
        assert(pStrstu->filedaddr != NULL);
        if (pStrstu->nFlag == 0)
        {
            for (i=0; i<pStrstu->nAmount; i++)
            {
                pStrstu->filedaddr[i] = buf + j;
                j = j + pStrstu->filedlen[i] + pStrstu->nCompartlen;
            }
        }
        else
        {
            p1 = buf;
            p2 = p1;
            while (p1 != NULL && i<= pStrstu->nAmount)
            {
                pStrstu->filedaddr[i] = p1;
                p2 = strstr(p1, pStrstu->szCompart);
                if (p2 == NULL)
                {
                    pStrstu->filedlen[i] = strlen(p1);
                    p1 = NULL;
                }
                else
                {
                    pStrstu->filedlen[i] = p2 - p1;
                    p1 = p2 + pStrstu->nCompartlen;
                }
                i++;
            }
        }
        return 0;
    }
    
    char * TrimString(char* szDest)  //去字符串 首尾 空白
    {
        int n, nLen;
        if (szDest != NULL)
        {
    
            for (n = strlen(szDest); n > 0; n--)
            {
                if (!isblank(szDest[n - 1]))  break;
            }
            szDest[n] = '';
    
            nLen = strlen(szDest);
            for (n = 0; n < nLen; n++)
            {
                if (!isblank(szDest[n])) break;
            }
            strcpy(szDest, szDest + n);
        }
        return szDest;
    }
    
    int strresvalue(char *buf, STRRESVAR Strstu, int nIndex, void *pValue, int nType) //报文数据域 读取
    {
        char szStrbuf[1024];
        assert(buf != NULL && pValue != NULL);
        assert(Strstu.filedlen != NULL && Strstu.filedaddr != NULL);
        assert(nIndex >=0 && nIndex < Strstu.nAmount);
        memset(szStrbuf, 0, sizeof(szStrbuf));
    
        strncpy(szStrbuf, Strstu.filedaddr[nIndex],Strstu.filedlen[nIndex]);
        TrimString(szStrbuf);
    
        switch (nType)
        {
            case STRINT :
                *(int *)pValue = atoi(szStrbuf);
                break ;
            case STRDOUBLE:
                *(double *)pValue = atoi(szStrbuf);
                break;
            default:
                strcpy((char *)pValue, szStrbuf);
                break;
        }
        return 0;
    }
    
    /*
    int main()
    {
        cout << "Test Message!" << endl;
    
        char szCestr[] = "0019999999999999999999kevinX  1234567.89";  //定长报文
        int nCelen[4] = {3, 19, 6, 12};
    
        int nIndex;
        char *nCeAddr[4], szAccno[20], szName[20];
        double fAmt;
        STRRESVAR stuStr;
        stuStr.nAmount = 4;
        stuStr.nFlag = 0;
        stuStr.filedlen = nCelen;
        stuStr.nCompartlen = 0;
        stuStr.szCompart[0] = 0;
        stuStr.filedaddr = nCeAddr;
    
        strrespre(szCestr, &stuStr);
        strresvalue(szCestr, stuStr, 0, &nIndex, STRINT);
        strresvalue(szCestr, stuStr, 1, szAccno, STRSTR);
        strresvalue(szCestr, stuStr, 2, szName, STRSTR);
        strresvalue(szCestr, stuStr, 3, &fAmt, STRDOUBLE);
    
        cout << "id = " << nIndex << endl;
        cout << "accno = " << szAccno << endl;
        cout << "name = " << szName << endl;
        cout << "amt = " << showpoint << fAmt << endl;
    
        return 0;
    }
    */
    
    int main()
    {
        cout << "Test Message!" << endl;
    
        char szCestr[] = "2|!88888888|!kevin_xiang|!1234567.89";	//定分割域报文
    
        int nIndex, nCeLen[4];
        char *nCeAddr[4], szAccno[20], szName[20];
    	double fAmt;
    	STRRESVAR stuStr;
        stuStr.nAmount = 4;
        stuStr.nFlag = 1;
        stuStr.filedlen = nCeLen;
        stuStr.nCompartlen = 2;
        strcpy(stuStr.szCompart, "|!");
        stuStr.filedaddr = nCeAddr;
        strrespre(szCestr, &stuStr);
    
        strresvalue(szCestr, stuStr, 0, &nIndex, STRINT);
        strresvalue(szCestr, stuStr, 1, szAccno, STRSTR);
        strresvalue(szCestr, stuStr, 2, szName, STRSTR);
        strresvalue(szCestr, stuStr, 3, &fAmt, STRDOUBLE);
    
        cout << "id = " << nIndex << endl;
        cout << "accno = " << szAccno << endl;
        cout << "name = " << szName << endl;
        cout << "amt = " << showpoint << fAmt << endl;
    
        return 0;
    }
    
    


     

    5. 示例二: linux下C读取 ini配置文档

    需要上面例一 申明的结构体与函数

    config.ini文件内容

    [SERVER]
    NUM=2

    [SERVER1]
    IP=192.168.0.1
    PORT=8888

    [SERVER2]
    IP=192.168.0.2
    PORT=5555

    int GetConfigStrValue(char *buf, void *pValue, int nType) //配置项字符串读写
    {
        char *nCeAddr[2];
        int nCeLen[2];
        STRRESVAR stuStr;
        stuStr.nAmount = 2;
        stuStr.nFlag = 1;
        stuStr.filedlen = nCeLen;
        stuStr.nCompartlen = 1;
        strcpy(stuStr.szCompart, "=");
        stuStr.filedaddr = nCeAddr;
        strrespre(buf, &stuStr);
        assert(strresvalue(buf, stuStr, 1, pValue, nType) == 0);
        return 0;
    }
    
    int GetConfigValue(char *szPath, char *szRoot, char *szName, void *pValue, int nType)	//配置文件读取
    {
        FILE *fp;
        int nFlag = 0;
        char buf[1024], szRootExt[100], szNameExt[100];
        assert( (fp = fopen(szPath, "r")) != NULL);
        sprintf(szRootExt, "[%s]", szRoot);
        sprintf(szNameExt, "%s=", szName);
        while (feof(fp) == 0)
        {
            memset(buf, 0, sizeof(buf));
            fgets(buf, sizeof(buf), fp);
            if (buf[0] == '#') continue;
    
            if (nFlag == 0 && buf[0] != '[') continue;
    
            else if (nFlag == 0 && buf[0] == '[')
            {
                if (strncmp(buf, szRootExt, strlen(szRootExt)) == 0) nFlag = 1;
            }
            else if (nFlag == 1 && buf[0] == '[')
            {
                break;
            }
            else
            {
                if (strncmp(buf, szNameExt, strlen(szNameExt)) == 0)
                {
                    assert(GetConfigStrValue(buf, pValue, nType) == 0);
                    fclose(fp);
                    return 0;
                }
            }
        }
        fclose(fp);
        return -1;
    }
    
    int main()
    {
        int nNumber, i, nPort;
        char szRoot[100], szIP[100];
    
        assert( GetConfigValue("./config.ini", "SERVER", "NUM", &nNumber, STRINT)==0 );
        cout << "No. = " << nNumber << endl;
    
        for( i=0; i<nNumber; i++ )
        {
            sprintf(szRoot, "SERVER%d", i+1);
            memset(szIP, 0, sizeof(szIP));
            GetConfigValue("./config.ini", szRoot, "IP", szIP, STRSTR);
            GetConfigValue("./config.ini", szRoot, "PORT", &nPort, STRINT);
            cout << "SERVER" << i+1 << " IP-->" << szIP << " PORT-->" << nPort << endl;
        }
    
        return 0;
    }


     

  • 相关阅读:
    面向对象的软件测试技术
    软件质量与软件测试
    测试方法
    测试计划的编写
    Monkey环境配置
    简单非线性关系数据集测试
    支持向量机
    最邻近规则分类
    Django1.9开发博客(14)- 集成Xadmin
    决策树
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648240.html
Copyright © 2011-2022 走看看