6.2远程打印
2016-04-09 15:53
417 查看
因为串口打印速度慢,调试程序会影响程序的真正效果,所以引入网络打印
debug_manager.h
debug_manager.c
netprint.c
netprint_client.c
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;
}
相关文章推荐
- VmProtect v2.12.3 安装注册
- 防止表单重复提交
- 转载:css隐藏元素的几种方案
- RN(react native)入坑指南-02,一个登录示例
- android 打 release包解决字节对其问题
- 又遇No result defined for action org.action.AddAction and result success
- 二分匹配题集
- JAVA round 和 floor的区别
- c#设计模式-单例模式
- Cortex-M3工作模式与异常
- Python 练习实例8
- 用angularjs做全选和反选遇到的问题
- static变量与static函数
- Android-->原生保存Bitmap(图片),压缩图片,创建图片缩略图和视频缩略图(任意大小)
- freemarker之生成静态页面
- 数据结构-栈的顺序结构两种方式
- Linux内核分析——进程描述与创建
- JspSmartUpload中文乱码问题解决
- Linux学习笔记11
- RN(react native)入坑指南-01,Hello RN,Windows下的环境搭建