一、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 DefaultDebugLevel 4
typedef struct DebugOpr {
char *name;
int isCanUse;
int (*DebugInit)(void);
int (*DebugExit)(void);
// int (*DebugPrintf)(const char *format, ...);
int (*DebugPrintf)(char* strData);
struct DebugOpr *ptNext;
}T_DebugOpr, *PT_DebugOpr;
int StdoutInit(void);
int NetInit(void);
int RegisterDebugOpr(PT_DebugOpr ptDebugOpr);
void ShowDebugOpr(void);
int SetDebugLevel(char *ucRecvBuf);
PT_DebugOpr GetDebugOpr(char *pcName);
int setDebugChannel(char * ucRecvBuf);
int DebugPrintf(const char * format,...);
int DebugInit(void);
int SelectAndInitChannel(void);
#endif /* _DEBUG_MANAGER_H */
二、debug_manager.c
#include <config.h>
#include <debug_manager.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
static PT_DebugOpr g_ptDebugOprHead;
static int g_iDebugLevelLimit = 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\n", i++, ptTmp->name);
ptTmp = ptTmp->ptNext;
}
}
int DebugInit(void)
{
int iError;
iError = StdoutInit();
iError |= NetInit();
return iError;
}
/*debuglevel=1,2,3...*/
int SetDebugLevel(char *ucRecvBuf)
{
g_iDebugLevelLimit = ucRecvBuf[12] - '0';
return 0;
}
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;
}
/*stdout = 0
* stdout = 1
* net =0
* net =1
**/
int setDebugChannel(char * ucRecvBuf)
{
char* pstrTmp;
char pstrName[100];
PT_DebugOpr ptTmp;
pstrTmp = strchr(ucRecvBuf, '=');
if(pstrTmp)
{
strncpy(pstrName, ucRecvBuf, pstrTmp - ucRecvBuf);
pstrName[pstrTmp-ucRecvBuf] = '\0';
ptTmp = GetDebugOpr(pstrName);
if(ptTmp)
{
if(pstrTmp[1] == '0')
{
ptTmp->isCanUse = 0;
}
else
{
ptTmp->isCanUse = 1;
}
return 0;
}
else
{
return -1;
}
}
else
{
return -1;
}
}
int DebugPrintf(const char * format,...)
{
/*Ö±½ÓʹÓÃvfprintf´òÓ¡*/
va_list tArgs;
int iRet;
char strTmpBuff[1024];
char *pcTmp;
int debuglevel = DefaultDebugLevel;
PT_DebugOpr ptTmp = g_ptDebugOprHead;
va_start(tArgs, format);
iRet = vsprintf(strTmpBuff, format, tArgs);
va_end(tArgs);
strTmpBuff[iRet] = '\0';
pcTmp = strTmpBuff;
/*ÉèÖôòÓ¡¼¶±ð, ÕâÀﲢδÓõ½´òÓ¡¼¶±ð*/
#if 0
if((strTmpBuff[0] == '<') && (strTmpBuff[2] == '>'))
{
debuglevel = strTmpBuff[1] - '0';
if((debuglevel >= 0) && (debuglevel <= 7))
{
pcTmp = strTmpBuff + 3;
}
else
{
debuglevel = DefaultDebugLevel;
}
}
if(debuglevel > g_iDebugLevelLimit)
{
return -1;
}
#endif
while(ptTmp)
{
if (ptTmp->isCanUse == 1)
{
ptTmp->DebugPrintf(pcTmp);
}
ptTmp = ptTmp->ptNext;
}
return 0;
}
int SelectAndInitChannel(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 <stdarg.h>
#include <stdio.h>
#include <string.h>
static int stdoutDebugInit(void);
static int stdoutDebugExit(void);
static int stdoutDebugPrintf(char* strData);
static T_DebugOpr g_tStdoutDebugOpr = {
.name = "stdout",
.isCanUse = 1,
.DebugInit = stdoutDebugInit,
.DebugExit = stdoutDebugExit,
.DebugPrintf = stdoutDebugPrintf,
};
static int stdoutDebugInit(void)
{
return 0;
}
static int stdoutDebugExit(void)
{
return 0;
}
static int stdoutDebugPrintf(char* strData)
{
printf("%s", strData);
return strlen(strData);
}
int StdoutInit(void)
{
return RegisterDebugOpr(&g_tStdoutDebugOpr);
}
四、netprintf.c //远程网络打印
#include <config.h>
#include <debug_manager.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>
#include <pthread.h>
static int netDebugInit(void);
static int netDebugExit(void);
static int netDebugPrintf(char* strData);
static int g_iSocketFd;
static struct sockaddr_in g_tServerSocketAddr;
static struct sockaddr_in g_tClinetSocketAddr;
#define PortNum 8888
#define NET_BUFF_SIZE (16*1024)
static unsigned char* g_pucNetBuff;
//static unsigned char* g_pucTmpBuff;
static int g_iReadPos = 0;
static int g_iWritePos = 0;
static pthread_t g_tSendThreadID;
static pthread_t g_tRecvThreadID;
static pthread_mutex_t g_tNetSendMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tNetSendCondvar = PTHREAD_COND_INITIALIZER;
static int g_isClinetConnected = 0;
static T_DebugOpr g_tNetDebugOpr = {
.name = "net",
.isCanUse = 1,
.DebugInit = netDebugInit,
.DebugExit = netDebugExit,
.DebugPrintf = netDebugPrintf,
};
/*»·Ðλº³åÇøº¯ÊýÉùÃ÷*/
static int isEmpty(void);
static int isFull(void);
static int PutData(char cVal);
static int GetData(char *pcVal);
static void *NetRecvThreadFunction(void *pvoid)
{
int iRecvLen;
int iSinSizeLen;
char ucRecvBuff[1000]; /*²»ÄÜʹÓÃunsigned char,·ñÔò²úÉú±àÒ뾯¸æ*/
struct sockaddr_in tClinetSocketAddr;
while(1)
{
iSinSizeLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(g_iSocketFd, ucRecvBuff, 999, 0, (struct sockaddr*)&tClinetSocketAddr, (socklen_t *)&iSinSizeLen);
if(iRecvLen > 0)
{
/*½âÎöÊý¾Ý*/
/* debuglevel = 0,1,2...
* stdout = 0|1
* net = 0|1
* setclinet
*/
ucRecvBuff[iRecvLen] = '\0';
if (strcmp(ucRecvBuff, "setclient") == 0)
{
g_tClinetSocketAddr = tClinetSocketAddr;
g_isClinetConnected = 1;
}
else if(strncmp(ucRecvBuff, "debuglevel=", 11) == 0)
{
SetDebugLevel(ucRecvBuff);
}
else
{
setDebugChannel(ucRecvBuff);
}
}
}
return NULL;
}
static void *NetSendThreadFunction(void *pvoid)
{
int iSinSizeLen;
int iSendlen;
char strTmpBuf[512];
int i ;
char cVal;
while(1)
{
/*ƽʱÐÝÃß*/
pthread_mutex_lock(&g_tNetSendMutex);
pthread_cond_wait(&g_tNetSendCondvar, &g_tNetSendMutex);
/* ±»»½ÐÑÖ®ºó*/
/*ʹÓÃsendtoº¯Êý°Ñ´Ó»·Ðλº³åÇøµÄÊý¾Ý·¢Ë͵½¿Í»§¶Ë*/
while(g_isClinetConnected && (!isEmpty()))
{
i = 0;
while((i<512) && (0 == GetData(&cVal)))
{
strTmpBuf[i] = cVal;
i++;
}
iSinSizeLen = sizeof(struct sockaddr);
iSendlen = sendto(g_iSocketFd, strTmpBuf, i, 0, (struct sockaddr *)&g_tClinetSocketAddr, (socklen_t)iSinSizeLen);
}
pthread_mutex_unlock(&g_tNetSendMutex);
}
return NULL;
}
static int netDebugInit(void)
{
/*socket³õʼ»¯*/
/* ·þÎñÆ÷¶Ë¿ªÊ¼½¨Á¢socketÃèÊö·û */
g_iSocketFd = socket( AF_INET, SOCK_DGRAM, 0);
if(g_iSocketFd == -1)
{
printf("socket error!\n");
return -1;
}
/* ·þÎñÆ÷¶ËÌî³ä sockaddr½á¹¹ */
g_tServerSocketAddr.sin_family = AF_INET;
g_tServerSocketAddr.sin_port = htons(PortNum);
g_tServerSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&(g_tServerSocketAddr.sin_zero), 0 , 8);
/* À¦°óg_iSocketFdÃèÊö·û */
if(bind( g_iSocketFd, (struct sockaddr *)(&g_tServerSocketAddr), sizeof(struct sockaddr)) == -1)
{
printf("bind error !\n");
return -1;
}
g_pucNetBuff = malloc(NET_BUFF_SIZE);
if(NULL == g_pucNetBuff)
{
printf("malloc g_pucNetBuff error!\n");
close(g_iSocketFd);
}
// g_pucTmpBuff = malloc(2*1024);
// if(NULL == g_pucTmpBuff)
// {
// printf("malloc g_pucTmpBuff error!\n");
// close(g_iSocketFd);
// free(g_pucNetBuff);
// }
/*´´½¨½ÓÊÕÏß³Ì*/
/*´´½¨·¢ËÍÏß³Ì*/
if(pthread_create(&g_tRecvThreadID, NULL, NetRecvThreadFunction, NULL))
{
printf("g_tRecvThreadID thread_create error!\n");
return -1;
}
if(pthread_create(&g_tSendThreadID, NULL, NetSendThreadFunction, NULL))
{
printf("g_tSendThreadID thread_create error!\n");
return -1;
}
return 0;
}
static int netDebugExit(void)
{
/*¹Ø±Õsocket*/
close(g_iSocketFd);
free(g_pucNetBuff);
// free(g_pucTmpBuff);
return 0;
}
/*¹¹Ôì»·Ðλº³åÇø*/
static int isFull(void)
{
return ((g_iWritePos + 1)%NET_BUFF_SIZE == g_iReadPos);
}
static int isEmpty(void)
{
return (g_iWritePos == g_iReadPos);
}
static int PutData(char cVal)
{
if(!isFull())
{
g_pucNetBuff[g_iWritePos] = cVal;
g_iWritePos = (g_iWritePos+1)%NET_BUFF_SIZE;
return 0;
}
else
{
return -1;
}
}
static int GetData(char *pcVal)
{
if(!isEmpty())
{
*pcVal = g_pucNetBuff[g_iReadPos];
g_iReadPos = (g_iReadPos+1)%NET_BUFF_SIZE;
return 0;
}
else
{
return -1;
}
}
static int netDebugPrintf(char * strData)
{
/*Êý¾Ý·ÅÈ뻺³åÇø£¬²Î¿¼vsprintfº¯Êý*/
// va_list tArgs;
// int iRet;
int i;
// int iNum = 2*1024;
// va_start(tArgs, format);
// iRet = vsprintf(g_pucTmpBuff, format, tArgs);
// va_end(tArgs);
// return iRet;
for(i=0; i< strlen(strData); i++)
{
if(PutData(strData[i]) == -1)
break;
}
/* µÈ´ý¿Í»§¶ËÁ¬½Ó*/
/*»½ÐÑÏß³Ì*/
pthread_mutex_lock(&g_tNetSendMutex);
pthread_cond_signal(&g_tNetSendCondvar);
pthread_mutex_unlock(&g_tNetSendMutex);
return i;
}
int NetInit(void)
{
return RegisterDebugOpr(&g_tNetDebugOpr);
}
五、客户端测试程序
netPrintfClinet.c
/*
* Usage:
* ./netPrintfClinet <server_IP> debuglevel =<0-8>
* ./netPrintfClinet <server_IP> stdout=0|1
* ./netPrintfClinet <server_IP> net=0|1
* ./netPrintfClinet <server_IP> show
*/
#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>
/* socket
* connect
* sendto/recvfrom
*/
#define PortNum 8888
#define MAX_MSG_SIZE 1024
int main(int argc , char ** argv)
{
int iSocketFd;
unsigned char ucSendBuff[MAX_MSG_SIZE];
unsigned char ucRecvBuff[MAX_MSG_SIZE];
int iSendlen;
int iRecvLen;
struct sockaddr_in tServerSocketAddr;
int iSinSizeLen;
if(argc != 3)
{
printf("Usage:\n");
printf(" %s <server_IP> debuglevel =<0-8>\n",argv[0]);
printf(" %s <server_IP> stdout=0|1\n",argv[0]);
printf(" %s <server_IP> net=0|1\n",argv[0]);
printf(" %s <server_IP> show\n",argv[0]);
return -1;
}
/* ¿Í»§¶Ë¿ªÊ¼½¨Á¢socketÃèÊö·û */
iSocketFd = socket( AF_INET, SOCK_DGRAM, 0);
if(iSocketFd == -1)
{
printf("socket error!\n");
return -1;
}
/* ·þÎñÆ÷¶ËÌî³ä sockaddr½á¹¹ */
tServerSocketAddr.sin_family = AF_INET;
tServerSocketAddr.sin_port = htons(PortNum);
// tServerSocketAddr.sin_addr = htonl(INADDR_ANY);
if (0 == inet_aton(argv[1], &tServerSocketAddr.sin_addr))
{
printf("invalid Server_Ip\n");
return -1;
}
memset(&(tServerSocketAddr.sin_zero), 0 , 8);
iSinSizeLen = sizeof(struct sockaddr);
if(strncmp(argv[2], "show", 4) == 0)
{
/*ÉèÖÿͻ§¶Ë£¬½ÓÊÕÊý¾Ý£¬ÏÔʾ*/
iSendlen = sendto(iSocketFd, "setclient", 9, 0, (struct sockaddr *)&tServerSocketAddr, (socklen_t)iSinSizeLen);
while(1)
{
iRecvLen = recvfrom(iSocketFd, ucRecvBuff, MAX_MSG_SIZE-1, 0, (struct sockaddr*)&tServerSocketAddr, (socklen_t *)&iSinSizeLen);
if(iRecvLen > 0)
{
ucRecvBuff[iRecvLen] = '\0';
printf("%s\n",ucRecvBuff);
}
}
}
else
{
/* ·¢ËÍ¿ØÖÆÃüÁî*/
iSendlen = sendto(iSocketFd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&tServerSocketAddr, (socklen_t)iSinSizeLen);
}
return 0;
}