linux应用程序_1_文本浏览器_9_网络打印_4_两个打印模块
两个打印模块:
1、串口打印
串口打印比较简单,直接使用printf即可,文末直接附上代码
2、网络打印(client.c是客户端代码,不同其他文件一起编译链接)
参考前面的TCP和UDP例程编写,这里使用的是UDP
初始化:
1、创建套接字
2、绑定服务器信息
3、分配缓存
4、创建发送线程和接收线程
static int NetDebugInit(void)
{
int iRet;
g_iServerFd = socket(AF_INET, SOCK_DGRAM, 0);
if(g_iServerFd < 0)
return -1;
g_tSocketServerAddr.sin_family = AF_INET;
g_tSocketServerAddr.sin_port = htons(SERVER_PORT);
g_tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(g_tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(g_iServerFd, (struct sockaddr *)&g_tSocketServerAddr, sizeof(struct sockaddr));
if(iRet < 0)
{
close(g_iServerFd);
return -1;
}
g_pcBuf = malloc(BUFFER_SIZE);
if(!g_pcBuf)
{
close(g_iServerFd);
return -1;
}
pthread_create(&g_tSendThreadId, NULL, &SendThread, NULL);
pthread_create(&g_tRecvThreadId, NULL, &RecvThread, NULL);
return 0;
}
发送线程:
平时休眠,当主线程需要打印信息,唤醒该线程,将调试信息打印到客户端
void *SendThread(void *pVoid)
{
char strBuf[PACKET_SIZE];
int iLen;
while(1)
{
pthread_mutex_lock(&g_tSendMutex);
pthread_cond_wait(&g_tSendCondvar, &g_tSendMutex);
pthread_mutex_unlock(&g_tSendMutex);
if(g_iHaveConnected)
{
while((iLen = GetDataFromBuf(strBuf)) > 0)
{
iLen = sendto(g_iServerFd, strBuf, iLen, 0, (struct sockaddr *)&g_tSocketClientAddr, sizeof(struct sockaddr));
}
}
}
return NULL;
}
接收线程:
平时休眠,当客户端向本服务器发送命令,线程由内核唤醒,解析命令并处理
void *RecvThread(void *pVoid)
{
int iAddrLen;
int iLen;
char strBuf[1024];
struct sockaddr_in tSocketClientAddr;
while(1)
{
iAddrLen = sizeof(struct sockaddr);
iLen = recvfrom(g_iServerFd, strBuf, 1023, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if(iLen <= 0)
continue ;
strBuf[iLen] = '\0';
if(strncmp(strBuf, "setstdoutdebug=", 15) == 0 || strncmp(strBuf, "setnetdebug=", 12) == 0)
{
SetDebugCanUse(strBuf);
}
else if(!strncmp(strBuf, "setdebuglevel=", 14))
{
SetDebugLevel(strBuf);
}
else if(!strcmp(strBuf, "setclient"))
{
g_tSocketClientAddr = tSocketClientAddr;
g_iHaveConnected = 1;
}
}
return NULL;
}
附代码:
stdout.c
#include <debug_manager.h>
#include <stdio.h>
#include <string.h>
static int StdoutDebugInit(void);
static int StdoutDebugExit(void);
static int StdoutDebugPrint(char *pcData);
T_DebugOpr g_tStdoutDebugOpr = {
.pcName = "stdoutdebug",
.iCanUse = 1,
.DebugInit = StdoutDebugInit,
.DebugExit = StdoutDebugExit,
.DebugPrint = StdoutDebugPrint,
};
static int StdoutDebugInit(void)
{
return 0;
}
static int StdoutDebugExit(void)
{
return 0;
}
static int StdoutDebugPrint(char *pcData)
{
printf("%s", pcData);
return strlen(pcData);
}
int StdoutInit(void)
{
return RegisterDebugOpr(&g_tStdoutDebugOpr);
}
netprint.c
#include <debug_manager.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#define BUFFER_SIZE (16*1024)
#define PACKET_SIZE (512)
#define SERVER_PORT 3456
static int NetDebugInit(void);
static int NetDebugExit(void);
static int NetDebugPrint(char *pcData);
static int g_iServerFd;
static struct sockaddr_in g_tSocketServerAddr;
static struct sockaddr_in g_tSocketClientAddr;
static char *g_pcBuf;
static int g_iWriteIndex;
static int g_iReadIndex;
static pthread_t g_tSendThreadId;
static pthread_t g_tRecvThreadId;
static pthread_mutex_t g_tSendMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tSendCondvar = PTHREAD_COND_INITIALIZER;
static int g_iHaveConnected;
T_DebugOpr g_tNetDebugOpr = {
.pcName = "netdebug",
.iCanUse = 1,
.DebugInit = NetDebugInit,
.DebugExit = NetDebugExit,
.DebugPrint = NetDebugPrint,
};
static int IsEmpty(void)
{
return (g_iReadIndex == g_iWriteIndex);
}
static int IsFull(void)
{
return (((g_iWriteIndex + 1) % BUFFER_SIZE) == g_iReadIndex);
}
static int PutDataToBuf(char *pcData)
{
int iCnt = 0;
while(iCnt < strlen(pcData))
{
if(IsFull())
break;
g_pcBuf[g_iWriteIndex] = pcData[iCnt];
g_iWriteIndex = (g_iWriteIndex + 1) % BUFFER_SIZE;
iCnt++;
}
return iCnt;
}
static int GetDataFromBuf(char strBuf[])
{
int iCnt = 0;
while(iCnt < PACKET_SIZE)
{
if(IsEmpty())
break;
strBuf[iCnt] = g_pcBuf[g_iReadIndex];
g_iReadIndex = (g_iReadIndex + 1) % BUFFER_SIZE;
iCnt++;
}
return iCnt;
}
void *SendThread(void *pVoid)
{
char strBuf[PACKET_SIZE];
int iLen;
while(1)
{
pthread_mutex_lock(&g_tSendMutex);
pthread_cond_wait(&g_tSendCondvar, &g_tSendMutex);
pthread_mutex_unlock(&g_tSendMutex);
if(g_iHaveConnected)
{
while((iLen = GetDataFromBuf(strBuf)) > 0)
{
iLen = sendto(g_iServerFd, strBuf, iLen, 0, (struct sockaddr *)&g_tSocketClientAddr, sizeof(struct sockaddr));
}
}
}
return NULL;
}
void *RecvThread(void *pVoid)
{
int iAddrLen;
int iLen;
char strBuf[1024];
struct sockaddr_in tSocketClientAddr;
while(1)
{
iAddrLen = sizeof(struct sockaddr);
iLen = recvfrom(g_iServerFd, strBuf, 1023, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if(iLen <= 0)
continue ;
strBuf[iLen] = '\0';
if(strncmp(strBuf, "setstdoutdebug=", 15) == 0 || strncmp(strBuf, "setnetdebug=", 12) == 0)
{
SetDebugCanUse(strBuf);
}
else if(!strncmp(strBuf, "setdebuglevel=", 14))
{
SetDebugLevel(strBuf);
}
else if(!strcmp(strBuf, "setclient"))
{
g_tSocketClientAddr = tSocketClientAddr;
g_iHaveConnected = 1;
}
}
return NULL;
}
static int NetDebugPrint(char *pcData)
{
int iRet;
pthread_mutex_lock(&g_tSendMutex);
iRet = PutDataToBuf(pcData);
pthread_mutex_unlock(&g_tSendMutex);
if(g_iHaveConnected)
{
pthread_cond_signal(&g_tSendCondvar);
}
return iRet;
}
static int NetDebugInit(void)
{
int iRet;
g_iServerFd = socket(AF_INET, SOCK_DGRAM, 0);
if(g_iServerFd < 0)
return -1;
g_tSocketServerAddr.sin_family = AF_INET;
g_tSocketServerAddr.sin_port = htons(SERVER_PORT);
g_tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(g_tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(g_iServerFd, (struct sockaddr *)&g_tSocketServerAddr, sizeof(struct sockaddr));
if(iRet < 0)
{
close(g_iServerFd);
return -1;
}
g_pcBuf = malloc(BUFFER_SIZE);
if(!g_pcBuf)
{
close(g_iServerFd);
return -1;
}
pthread_create(&g_tSendThreadId, NULL, &SendThread, NULL);
pthread_create(&g_tRecvThreadId, NULL, &RecvThread, NULL);
return 0;
}
static int NetDebugExit(void)
{
pthread_mutex_destroy(&g_tSendMutex);
pthread_cond_destroy(&g_tSendCondvar);
free(g_pcBuf);
close(g_iServerFd);
return 0;
}
int NetInit(void)
{
return RegisterDebugOpr(&g_tNetDebugOpr);
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#define SERVER_PORT 3456
int main(int argc,char **argv)
{
int iServerFd, iClientFd;
int iRet;
struct sockaddr_in tSocketServerAddr;
char strBuf[1024];
int iLen;
int iAddrLen;
if(argc != 3)
{
printf("Usage : %s <server_ip> setdebuglevel=<0-7>\r\n", argv[0]);
printf("Usage : %s <server_ip> setstdoutdebug=<0|1>\r\n", argv[0]);
printf("Usage : %s <server_ip> setnetdebug=<0|1>\r\n", argv[0]);
printf("Usage : %s <server_ip> show\r\n", argv[0]);
return -1;
}
iClientFd = socket(AF_INET, SOCK_DGRAM, 0);
if(iClientFd < 0)
{
printf("socket error\r\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT);
if(!inet_aton(argv[1], &tSocketServerAddr.sin_addr))
{
printf("ivalid server_ip\r\n");
goto error;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
if(!strcmp(argv[2], "show"))
{
iAddrLen = sizeof(struct sockaddr);
iLen = sendto(iClientFd, "setclient", 9, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
printf("send msg %s\r\n", "setclient");
while(1)
{
iAddrLen = sizeof(struct sockaddr);
iLen = recvfrom(iClientFd, strBuf, 1023, 0, (struct sockaddr *)&tSocketServerAddr, &iAddrLen);
strBuf[iLen] = '\0';
printf("%s", strBuf);
}
}
printf("send msg %s\r\n", argv[2]);
iLen = sendto(iClientFd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
close(iClientFd);
return 0;
error:
close(iClientFd);
return -1;
}