您的位置:首页 > 其它

6.2远程打印

2016-04-09 15:53 417 查看
因为串口打印速度慢,调试程序会影响程序的真正效果,所以引入网络打印

debug_manager.h

#ifndef_DEBUG_MANAGER_H
#define_DEBUG_MANAGER_H

#defineAPP_EMERG"<0>"/*systemisunusable*/
#defineAPP_ALERT"<1>"/*actionmustbetakenimmediately*/
#defineAPP_CRIT"<2>"/*criticalconditions*/
#defineAPP_ERR"<3>"/*errorconditions*/
#defineAPP_WARNING"<4>"/*warningconditions*/
#defineAPP_NOTICE"<5>"/*normalbutsignificantcondition*/
#defineAPP_INFO"<6>"/*informational*/
#defineAPP_DEBUG"<7>"/*debug-levelmessages*/

#defineDEFAULT_DBGLEVEL4

typedefstructDebugOpr{
char*name;
intisCanUse;
int(*DebugInit)(void);
int(*DebugExit)(void);
int(*DebugPrint)(char*strData);
structDebugOpr*ptNext;
}T_DebugOpr,*PT_DebugOpr;

intRegisterDebugOpr(PT_DebugOprptDebugOpr);
voidShowDebugOpr(void);
PT_DebugOprGetDebugOpr(char*pcName);
intSetDbgLevel(char*strBuf);
intSetDbgChanel(char*strBuf);
intDebugInit(void);
intDebugPrint(constchar*pcFormat,...);
intInitDebugChanel(void);
intNetPrintInit(void);
intStdoutInit(void);

#endif/*_DEBUG_MANAGER_H*/


debug_manager.c

#include<config.h>
#include<debug_manager.h>
#include<string.h>
#include<stdio.h>
#include<stdarg.h>

staticPT_DebugOprg_ptDebugOprHead;
staticintg_iDbgLevelLimit=8;//允许所有级别打印信息

intRegisterDebugOpr(PT_DebugOprptDebugOpr)
{
PT_DebugOprptTmp;

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;
}

return0;
}

voidShowDebugOpr(void)
{
inti=0;
PT_DebugOprptTmp=g_ptDebugOprHead;

while(ptTmp)
{
printf("%02d%s\n",i++,ptTmp->name);
ptTmp=ptTmp->ptNext;
}
}

PT_DebugOprGetDebugOpr(char*pcName)
{
PT_DebugOprptTmp=g_ptDebugOprHead;

while(ptTmp)
{
if(strcmp(ptTmp->name,pcName)==0)
{
returnptTmp;
}
ptTmp=ptTmp->ptNext;
}
returnNULL;
}

/*strBuf="dbglevel=<0-7>"*/
intSetDbgLevel(char*strBuf)
{
g_iDbgLevelLimit=strBuf[9]-'0';
return0;
}

/*
*stdout=0:关闭stdout打印
*stdout=1:打开staout打印
*netprint=0:关闭netprint打印
*netprint=1:打开netprint打印
*/

intSetDbgChanel(char*strBuf)
{
char*pStrTmp;
charstrName[100];
PT_DebugOprptTmp;

pStrTmp=strchr(strBuf,'=');//返回指向‘=’的指针
if(!pStrTmp)
{
return-1;
}
else
{
strncpy(strName,strBuf,pStrTmp-strBuf);
strName[pStrTmp-strBuf]='\0';
ptTmp=GetDebugOpr(strName);
if(!ptTmp)
return-1;

if(pStrTmp[1]=='0')
ptTmp->isCanUse=0;
else
ptTmp->isCanUse=1;
return0;
}

}

intDebugPrint(constchar*pcFormat,...)
{
charstrTmpBuf[1000];
char*pcTmp;
va_listtArg;
intiNum;
PT_DebugOprptTmp=g_ptDebugOprHead;
intdbglevel=DEFAULT_DBGLEVEL;

va_start(tArg,pcFormat);
iNum=vsprintf(strTmpBuf,pcFormat,tArg);
va_end(tArg);
strTmpBuf[iNum]='\0';

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;
}

return0;

}

intDebugInit(void)
{
intiError;

iError=StdoutInit();
iError|=NetPrintInit();
returniError;
}

intInitDebugChanel(void)
{
PT_DebugOprptTmp=g_ptDebugOprHead;
while(ptTmp)
{
if(ptTmp->isCanUse&&ptTmp->DebugInit)
{
ptTmp->DebugInit();
}
ptTmp=ptTmp->ptNext;
}

return0;
}
stdout.c

#include<config.h>
#include<debug_manager.h>
#include<stdio.h>
#include<string.h>

staticintStdoutDebugPrint(char*strData)
{
/*直接把输出信息用printf打印出来*/
printf("%s",strData);
returnstrlen(strData);
}

staticT_DebugOprg_tStdoutDbgOpr={
.name="stdout",
.isCanUse=1,
.DebugPrint=StdoutDebugPrint,
};

intStdoutInit(void)
{
returnRegisterDebugOpr(&g_tStdoutDbgOpr);
}


netprint.c

#include<config.h>
#include<debug_manager.h>
#include<sys/types.h>/*SeeNOTES*/
#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>

#defineSERVER_PORT5678
#definePRINT_BUF_SIZE(16*1024)

staticintg_iSocketServer;
staticstructsockaddr_ing_tSocketServerAddr;
staticstructsockaddr_ing_tSocketClientAddr;
staticintg_iHaveConnected=0;
staticchar*g_pcNetPrintBuf;
staticintg_iReadPos=0;
staticintg_iWritePos=0;

staticpthread_tg_tSendTreadID;//发送线程ID
staticpthread_tg_tRecvTreadID;//接收线程ID

staticpthread_mutex_tg_tNetDbgSendMutex=PTHREAD_MUTEX_INITIALIZER;
staticpthread_cond_tg_tNetDbgSendConVar=PTHREAD_COND_INITIALIZER;

staticintisFull(void)
{
/*写数据追上读数据的时候满啦*/
return(((g_iWritePos+1)%PRINT_BUF_SIZE)==g_iReadPos);
}

staticintisEmpty(void)
{
return(g_iWritePos==g_iReadPos);
}

staticintPutData(charcVal)
{
if(isFull())
return-1;
else
{
g_pcNetPrintBuf[g_iWritePos]=cVal;
g_iWritePos=(g_iWritePos+1)%PRINT_BUF_SIZE;
return0;
}
}

staticintGetData(char*pcVal)
{
if(isEmpty())
return-1;
else
{
*pcVal=g_pcNetPrintBuf[g_iReadPos];
g_iReadPos=(g_iReadPos+1)%PRINT_BUF_SIZE;
return0;
}
}

staticvoid*NetDbgSendTreadFunction(void*pVoid)
{
charstrTmpBuf[512];
charcVal;
inti;
intiAddrLen;
intiSendLen;

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(structsockaddr);
iSendLen=sendto(g_iSocketServer,strTmpBuf,i,0,
(conststructsockaddr*)&g_tSocketClientAddr,iAddrLen);

}

}
returnNULL;
}

staticvoid*NetDbgRecvTreadFunction(void*pVoid)
{
socklen_tiAddrLen;
intiRecvLen;
charucRecvBuf[1000];
structsockaddr_intSocketClientAddr;

while(1)
{
iAddrLen=sizeof(structsockaddr);
DBG_PRINTF("inNetDbgRecvTreadFunction\n");
iRecvLen=recvfrom(g_iSocketServer,ucRecvBuf,999,0,(structsockaddr*)&tSocketClientAddr,&iAddrLen);

if(iRecvLen>0)
{
ucRecvBuf[iRecvLen]='\0';
DBG_PRINTF("netprint.cgetmsg:%s\n",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;
}
elseif(strncmp(ucRecvBuf,"dbglevel=",9)==0)
{
SetDbgLevel(ucRecvBuf);
}
else
{
SetDbgChanel(ucRecvBuf);
}
}

}
returnNULL;
}

staticintNetDbgInit(void)
{
/*初始化socket*/

intiRet;

g_iSocketServer=socket(AF_INET,SOCK_DGRAM,0);
if(-1==g_iSocketServer)
{
printf("socketerror!\n");
return-1;
}

g_tSocketServerAddr.sin_family=AF_INET;
g_tSocketServerAddr.sin_port=htons(SERVER_PORT);/*hosttonet,short*/
g_tSocketServerAddr.sin_addr.s_addr=INADDR_ANY;
memset(g_tSocketServerAddr.sin_zero,0,8);

iRet=bind(g_iSocketServer,(conststructsockaddr*)&g_tSocketServerAddr,sizeof(structsockaddr));
if(-1==iRet)
{
printf("binderror!\n");
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);

return0;
}

staticintNetDbgExit(void)
{
/*关闭socket,...*/
close(g_iSocketServer);
free(g_pcNetPrintBuf);
}

staticintNetDbgPrint(char*strData)
{
/*把数据放入环形缓冲区,*/
inti;

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);

returni;

}

staticT_DebugOprg_tNetDbgOpr={
.name="netprint",
.isCanUse=1,
.DebugInit=NetDbgInit,
.DebugExit=NetDbgExit,
.DebugPrint=NetDbgPrint,
};

intNetPrintInit(void)
{
returnRegisterDebugOpr(&g_tNetDbgOpr);
}


netprint_client.c

#include<sys/types.h>/*SeeNOTES*/
#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
*/
#defineSERVER_PORT5678

/*
*./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,²¢ÇÒ½ÓÊÕ´òÓ¡ÐÅÏ¢
*/

intmain(intargc,char**argv)
{
intiSocketClient;
structsockaddr_intSocketServerAddr;

intiRet;
unsignedcharucRecvBuf[1000];
intiSendLen;
intiAddrLen;
intiRecvLen;
if(argc!=3)
{
printf("Usage:\n");
printf("%s<server_ip>dbglevel=<0-9>\n",argv[0]);
printf("%s<server_ip>stdout=0|1\n",argv[0]);
printf("%s<server_ip>netprint=0|1\n",argv[0]);
printf("%s<server_ip>show\n",argv[0]);
return-1;
}

iSocketClient=socket(AF_INET,SOCK_DGRAM,0);

tSocketServerAddr.sin_family=AF_INET;
tSocketServerAddr.sin_port=htons(SERVER_PORT);/*hosttonet,short*/
if(0==inet_aton(argv[1],&tSocketServerAddr.sin_addr))/*±¾»úÉϵÄËùÓÐIP*/
{
printf("invalidserver_ip\n");
return-1;
}
memset(tSocketServerAddr.sin_zero,0,8);/*ÉèÖÃÎÞÓõĿռäΪ0*/

if(strcmp(argv[2],"show")==0)
{
/*·¢ËÍÊý¾Ý*/
iAddrLen=sizeof(structsockaddr);
iSendLen=sendto(iSocketClient,"setclient",9,0,
(conststructsockaddr*)&tSocketServerAddr,iAddrLen);

while(1)
{
/*Ñ­»·:´ÓÍøÂç¶ÁÊý¾Ý,´òÓ¡³öÀ´*/
iAddrLen=sizeof(structsockaddr);
iRecvLen=recvfrom(iSocketClient,ucRecvBuf,999,0,(structsockaddr*)&tSocketServerAddr,&iAddrLen);
if(iRecvLen>0)
{
ucRecvBuf[iRecvLen]='\0';
printf("%s\n",ucRecvBuf);
}
}
}
else
{
/*·¢ËÍÊý¾Ý*/
iAddrLen=sizeof(structsockaddr);
iSendLen=sendto(iSocketClient,argv[2],strlen(argv[2]),0,
(conststructsockaddr*)&tSocketServerAddr,iAddrLen);
}

return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: