zoukankan      html  css  js  c++  java
  • 6.2远程打印

    因为串口打印速度慢,调试程序会影响程序的真正效果,所以引入网络打印

    debug_manager.h

    #ifndef _DEBUG_MANAGER_H
    #define _DEBUG_MANAGER_H
    
    #define    APP_EMERG    "<0>"    /* system is unusable            */
    #define    APP_ALERT    "<1>"    /* action must be taken immediately    */
    #define    APP_CRIT    "<2>"    /* critical conditions            */
    #define    APP_ERR            "<3>"    /* error conditions            */
    #define    APP_WARNING    "<4>"    /* warning conditions            */
    #define    APP_NOTICE    "<5>"    /* normal but significant condition    */
    #define    APP_INFO    "<6>"    /* informational            */
    #define    APP_DEBUG    "<7>"    /* debug-level messages            */
    
    #define DEFAULT_DBGLEVEL  4
    
    typedef struct DebugOpr {
        char *name;
        int isCanUse;
        int (*DebugInit)(void);
        int (*DebugExit)(void);
        int (*DebugPrint)(char *strData);    
        struct DebugOpr *ptNext;
    }T_DebugOpr, *PT_DebugOpr;
    
    int RegisterDebugOpr(PT_DebugOpr ptDebugOpr);
    void ShowDebugOpr(void);
    PT_DebugOpr GetDebugOpr(char *pcName);
    int SetDbgLevel(char *strBuf);
    int SetDbgChanel(char *strBuf);
    int DebugInit(void);
    int DebugPrint(const char *pcFormat, ...);
    int InitDebugChanel(void);
    int NetPrintInit(void);
    int StdoutInit(void);
    
    #endif /* _DEBUG_MANAGER_H */

    debug_manager.c

    #include <config.h>
    #include <debug_manager.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdarg.h>
    
    static PT_DebugOpr g_ptDebugOprHead;
    static int g_iDbgLevelLimit = 8;        //允许所有级别打印信息
    
    int RegisterDebugOpr(PT_DebugOpr ptDebugOpr)
    {
        PT_DebugOpr ptTmp;
    
        if (!g_ptDebugOprHead)
        {
            g_ptDebugOprHead   = ptDebugOpr;
            ptDebugOpr->ptNext = NULL;
        }
        else
        {
            ptTmp = g_ptDebugOprHead;
            while (ptTmp->ptNext)
            {
                ptTmp = ptTmp->ptNext;
            }
            ptTmp->ptNext      = ptDebugOpr;
            ptDebugOpr->ptNext = NULL;
        }
    
        return 0;
    }
    
    
    void ShowDebugOpr(void)
    {
        int i = 0;
        PT_DebugOpr ptTmp = g_ptDebugOprHead;
    
        while (ptTmp)
        {
            printf("%02d %s
    ", i++, ptTmp->name);
            ptTmp = ptTmp->ptNext;
        }
    }
    
    PT_DebugOpr GetDebugOpr(char *pcName)
    {
        PT_DebugOpr ptTmp = g_ptDebugOprHead;
        
        while (ptTmp)
        {
            if (strcmp(ptTmp->name, pcName) == 0)
            {
                return ptTmp;
            }
            ptTmp = ptTmp->ptNext;
        }
        return NULL;
    }
    
    /* strBuf = "dbglevel=<0-7>" */
    int SetDbgLevel(char *strBuf)
    {
        g_iDbgLevelLimit = strBuf[9] - '0';
        return 0;
    }
    
    /*
     *stdout   = 0               :关闭stdout打印
     *stdout   = 1               :打开staout打印
     *netprint = 0               :关闭netprint打印
     *netprint = 1               :打开netprint打印
     */
    
    int SetDbgChanel(char *strBuf)
    {
        char *pStrTmp;
        char strName[100];
        PT_DebugOpr ptTmp;
        
        pStrTmp = strchr(strBuf,'=');        //返回指向‘=’的指针
        if(!pStrTmp)
        {
            return -1;
        }
        else
        {
            strncpy(strName, strBuf, pStrTmp-strBuf);
            strName[pStrTmp-strBuf] = '';
            ptTmp = GetDebugOpr(strName);
            if(!ptTmp)
                return -1;
    
            if(pStrTmp[1] == '0')
                ptTmp->isCanUse = 0;
            else
                ptTmp->isCanUse = 1;
            return 0;
        }
        
    }
    
    
    int DebugPrint(const char *pcFormat, ...)
    {
        char strTmpBuf[1000];
        char *pcTmp;
        va_list tArg;
        int iNum;
        PT_DebugOpr ptTmp = g_ptDebugOprHead;
        int dbglevel = DEFAULT_DBGLEVEL;
        
        va_start (tArg, pcFormat);
        iNum = vsprintf (strTmpBuf, pcFormat, tArg);
        va_end (tArg);
        strTmpBuf[iNum] = '';
    
    
        pcTmp = strTmpBuf;
        
        /* 根据打印级别决定是否打印 */
        if((strTmpBuf[0] == '<') && (strTmpBuf[2] == '>'))
        {
            dbglevel = strTmpBuf[1] - '0';
            if (dbglevel >= 0 && dbglevel <= 9)
            {
                pcTmp = strTmpBuf + 3;
            }
            else
            {
                dbglevel = DEFAULT_DBGLEVEL;
            }
        }
    
        if (dbglevel > g_iDbgLevelLimit)
        {
            return -1;
        }
    
        
        /* 调用链表中所有isCanUse为1的结构体的DebugPrint函数 */
    
        while (ptTmp)
        {
            if(ptTmp->isCanUse)
            {
                ptTmp->DebugPrint(pcTmp);
            }
            ptTmp = ptTmp->ptNext;
        }
    
        return 0;
        
    }
    
    int DebugInit(void)
    {
        int iError;
    
        iError = StdoutInit();
        iError |= NetPrintInit();
        return iError;
    }
    
    int InitDebugChanel(void)
    {
        PT_DebugOpr ptTmp = g_ptDebugOprHead;
        while (ptTmp)
        {
            if(ptTmp->isCanUse && ptTmp->DebugInit)
            {
                ptTmp->DebugInit();
            }
            ptTmp = ptTmp->ptNext;
        }
    
        return 0;
    }
     
     
    stdout.c
    #include <config.h>
    #include <debug_manager.h>
    #include <stdio.h>
    #include <string.h>
    
    
    static int StdoutDebugPrint(char *strData)
    {
        /* 直接把输出信息用printf打印出来 */
        printf("%s", strData);
        return strlen(strData);    
    }
    
    static T_DebugOpr g_tStdoutDbgOpr = {
        .name       = "stdout",
        .isCanUse   = 1,
        .DebugPrint = StdoutDebugPrint,
    };
    
    int StdoutInit(void)
    {
        return RegisterDebugOpr(&g_tStdoutDbgOpr);
    }

    netprint.c

    #include <config.h>
    #include <debug_manager.h>
    #include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    #define SERVER_PORT 5678
    #define PRINT_BUF_SIZE (16 * 1024)
    
    static int g_iSocketServer;
    static struct sockaddr_in g_tSocketServerAddr;
    static struct sockaddr_in g_tSocketClientAddr;
    static int g_iHaveConnected = 0;
    static char *g_pcNetPrintBuf;    
    static int g_iReadPos  = 0;
    static int g_iWritePos = 0;
    
    static pthread_t g_tSendTreadID;    //发送线程ID
    static pthread_t g_tRecvTreadID;    //接收线程ID
    
    static pthread_mutex_t g_tNetDbgSendMutex  = PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t  g_tNetDbgSendConVar = PTHREAD_COND_INITIALIZER;
    
    static int isFull(void)
    {    
        /* 写数据追上读数据的时候满啦 */
        return (((g_iWritePos + 1) % PRINT_BUF_SIZE) == g_iReadPos);
    }
    
    static int isEmpty(void)
    {
        return (g_iWritePos == g_iReadPos);
    }
    
    
    static int PutData(char cVal)
    {
        if(isFull())
            return -1;
        else
        {
            g_pcNetPrintBuf[g_iWritePos] = cVal;
            g_iWritePos = (g_iWritePos + 1) % PRINT_BUF_SIZE;
            return 0;
        }
    }
    
    static int GetData(char *pcVal)
    {
        if(isEmpty())
            return -1;
        else
        {
            *pcVal = g_pcNetPrintBuf[g_iReadPos];
            g_iReadPos = (g_iReadPos + 1) % PRINT_BUF_SIZE;
            return 0;
        }
    }
    
    
    static void *NetDbgSendTreadFunction(void *pVoid)
    {    
        char strTmpBuf[512];
        char cVal;
        int i;
        int iAddrLen;
        int iSendLen;
    
        while(1)
        {
            /* 平时休眠 */
            pthread_mutex_lock(&g_tNetDbgSendMutex);
            pthread_cond_wait(&g_tNetDbgSendConVar, &g_tNetDbgSendMutex);    
            pthread_mutex_unlock(&g_tNetDbgSendMutex);
            
            /* 条件等待函数 */
            while((g_iHaveConnected && !isEmpty()))
            {
                i = 0;
    
                /* 把环形缓冲区的数据最多取512字节 */
                while((i < 512)  &&  (0 == GetData(&cVal)))
                {
                    strTmpBuf[i] = cVal;
                    i++;
                }
                /* 程序能够向下继续证明被唤醒啦 */
                /* 用sendto函数发送打印信息到客户端 */
                
                iAddrLen = sizeof(struct sockaddr);
                iSendLen = sendto(g_iSocketServer, strTmpBuf, i, 0,
                                      (const struct sockaddr *)&g_tSocketClientAddr, iAddrLen);
    
            }
                
        }
        return NULL;
    }
    
    static void *NetDbgRecvTreadFunction(void *pVoid)
    {
        socklen_t iAddrLen;
        int iRecvLen;
        char ucRecvBuf[1000];
        struct sockaddr_in tSocketClientAddr;
        
        while(1)
        {
            iAddrLen = sizeof(struct sockaddr);
            DBG_PRINTF("in NetDbgRecvTreadFunction
    ");
            iRecvLen = recvfrom(g_iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
            
            if(iRecvLen > 0)
            {
                ucRecvBuf[iRecvLen] = '';
                DBG_PRINTF("netprint.c get msg: %s
    ", ucRecvBuf);
                
                /* 解析数据 :
                 * setclient            : 设置接收打印信息的客户端
                 * dbglevel=0,1,2...    : 修改打印级别
                *stdout   = 0               :关闭stdout打印
                 * stdout=1             : 打开stdout打印
                *netprint = 0               :关闭netprint打印
                *netprint = 1               :打开netprint打印
                */
                if(strcmp(ucRecvBuf, "setclient") == 0)
                {
                    /* 成功连接且设置为 */
                    g_tSocketClientAddr = tSocketClientAddr;
                    g_iHaveConnected = 1;
                }
                else if (strncmp(ucRecvBuf, "dbglevel=", 9) == 0)
                {
                    SetDbgLevel(ucRecvBuf);    
                }
                else
                {
                    SetDbgChanel(ucRecvBuf);
                }
            }
            
        }
        return NULL;
    }
    
    
    static int NetDbgInit(void)
    {
        /* 初始化socket */
    
        int iRet;
        
        g_iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
        if (-1 == g_iSocketServer)
        {
            printf("socket error!
    ");
            return -1;
        }
    
        g_tSocketServerAddr.sin_family      = AF_INET;
        g_tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
         g_tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
        memset(g_tSocketServerAddr.sin_zero, 0, 8);
        
        iRet = bind(g_iSocketServer, (const struct sockaddr *)&g_tSocketServerAddr, sizeof(struct sockaddr));
        if (-1 == iRet)
        {
            printf("bind error!
    ");
            return -1;
        }
    
        g_pcNetPrintBuf = malloc(PRINT_BUF_SIZE);
        if(NULL == g_pcNetPrintBuf)
        {
            close(g_iSocketServer);
            return -1;
        }
    
        /* 创建netprint发送线程: 它用来发送打印信息给客户端 */
        pthread_create(&g_tSendTreadID, NULL, NetDbgSendTreadFunction, NULL);            
    
        /* 创建netprint接收线否: 用来接收控制信息,比如修改打印级别,打开/关闭打印 */
        pthread_create(&g_tRecvTreadID, NULL, NetDbgRecvTreadFunction, NULL);            
            
        return 0;
    }
    
    static int NetDbgExit(void)
     {
        /* 关闭socket,... */
        close(g_iSocketServer);
        free(g_pcNetPrintBuf);
     }
    
    static int NetDbgPrint(char *strData)
     {
         /* 把数据放入环形缓冲区, */
        int i;
        
        for(i = 0; i < strlen(strData); i++)
        {
            if(0 != PutData(strData[i]))
                break;
        }
        
        /* 如果已经有客户端连接了, 就把数据通过网络发送给客户端 */
        /* 唤醒netprint的发送线程 */
        pthread_mutex_lock(&g_tNetDbgSendMutex);
        pthread_cond_signal(&g_tNetDbgSendConVar);
        pthread_mutex_unlock(&g_tNetDbgSendMutex);
    
        return i;
        
     }
    
    
    static T_DebugOpr g_tNetDbgOpr = {
        .name       = "netprint",
        .isCanUse   = 1,
        .DebugInit  = NetDbgInit,
        .DebugExit  = NetDbgExit,
        .DebugPrint = NetDbgPrint,
    };
    
    int NetPrintInit(void)
    {
        return RegisterDebugOpr(&g_tNetDbgOpr);
    }

    netprint_client.c

    #include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    
    
    
    /*socket
    * connet
    * send/recv
    */
    #define SERVER_PORT 5678
    
    /*
     * ./netprint_client <server_ip> dbglevel=<0-9>
     * ./netprint_client <server_ip> stdout=0|1
     * ./netprint_client <server_ip> netprint=0|1
     * ./netprint_client <server_ip> show // setclient,²¢ÇÒ½ÓÊÕ´òÓ¡ÐÅÏ¢
     */
    
    
    int main(int argc, char **argv)
    {
        int iSocketClient;
        struct sockaddr_in tSocketServerAddr;
    
        int iRet;
        unsigned char ucRecvBuf[1000];
        int iSendLen;
        int iAddrLen;
        int iRecvLen;
        if (argc != 3)
        {
            printf("Usage:
    ");
            printf("%s <server_ip> dbglevel=<0-9>
    ", argv[0]);
            printf("%s <server_ip> stdout=0|1
    ", argv[0]);
            printf("%s <server_ip> netprint=0|1
    ", argv[0]);
            printf("%s <server_ip> show
    ", argv[0]);
            return -1;
        }
    
        
        iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
        
        tSocketServerAddr.sin_family      = AF_INET;
        tSocketServerAddr.sin_port        = htons(SERVER_PORT);   /* host to net ,short */
        if(0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))  /* ±¾»úÉϵÄËùÓÐIP */
        {
            printf("invalid server_ip
    ");
            return -1;
        }
        memset(tSocketServerAddr.sin_zero, 0, 8);                  /* ÉèÖÃÎÞÓõĿռäΪ0 */
    
    
        if (strcmp(argv[2], "show") == 0)
        {
            /* ·¢ËÍÊý¾Ý */
            iAddrLen = sizeof(struct sockaddr);
            iSendLen = sendto(iSocketClient, "setclient", 9, 0,
                                  (const struct sockaddr *)&tSocketServerAddr, iAddrLen);
    
            while (1)
            {
                /* Ñ­»·: ´ÓÍøÂç¶ÁÊý¾Ý, ´òÓ¡³öÀ´ */
                iAddrLen = sizeof(struct sockaddr);
                iRecvLen = recvfrom(iSocketClient, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketServerAddr, &iAddrLen);
                if (iRecvLen > 0)
                {
                    ucRecvBuf[iRecvLen] = '';
                    printf("%s
    ", ucRecvBuf);
                }
            }
        }
        else
        {
            /* ·¢ËÍÊý¾Ý */
            iAddrLen = sizeof(struct sockaddr);
            iSendLen = sendto(iSocketClient, argv[2], strlen(argv[2]), 0,
                                  (const struct sockaddr *)&tSocketServerAddr, iAddrLen);
        }
    
    
        return 0;
    }
  • 相关阅读:
    委托与事件
    Winform 窗体闪烁 & 任务栏提示
    Main函数
    WPF数据虚拟化
    异步编程、线程和任务
    内存管理与垃圾回收
    Winform 获取桌面设备上下文
    全选,反选,全不选以及计算价格,删除
    全选、反选、删除
    解析数据图片自动轮播——圆点
  • 原文地址:https://www.cnblogs.com/CZM-/p/5371797.html
Copyright © 2011-2022 走看看