简单UDP日志程序
来源:互联网 发布:php.ini 大文件大小 编辑:程序博客网 时间:2024/05/20 04:49
使用简单的宏Trace(...)就可以将字符串发送到指定的Udp服务端进行实时显示,Trace用法类似如printf传入可变参数,
它前两个参数是隐藏起来的分别是:文件名和行号,这样方便我们查找打印日志所在位置。
WTL库安装下载地址:http://www.cnblogs.com/tujiaw/archive/2011/02/26/3059245.html
首先在对话框创建的时候初始化socket,创建接收数据线程
双击单行可以将日志拷贝到剪切板上
源码是用vs2012编译的,只需要关注MainFrm.h文件就可以了,拷贝数据到剪切板代码在ShowTraceView.h中
它前两个参数是隐藏起来的分别是:文件名和行号,这样方便我们查找打印日志所在位置。
下面是完整客户端代码:
#include <stdio.h>#include <stdarg.h>#include <string>#include <Windows.h>#include <process.h>#include <time.h>#pragma comment(lib, "ws2_32.lib")#define Trace CTrace(__FILE__, __LINE__)class CUdpClient{public: CUdpClient(const std::string &ip=std::string("127.0.0.1"), unsigned short port=5050) { init(ip, port); } void init(const std::string &ip, unsigned short port) { sock_ = INVALID_SOCKET; memset(&sin_, 0, sizeof(sin_)); sin_.sin_family = AF_INET; sin_.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); sin_.sin_port = htons(port); addrLen_ = sizeof(sin_); } ~CUdpClient() { closesocket(sock_); } int send(const std::string &str) { if (INVALID_SOCKET == sock_) { sock_ = socket(AF_INET, SOCK_DGRAM, 0); } if (INVALID_SOCKET != sock_) { return sendto(sock_, str.c_str(), str.size(), 0, (SOCKADDR*)&sin_, addrLen_); } return 0; }private: SOCKET sock_; sockaddr_in sin_; int addrLen_;};class CTrace{public: CTrace(const char *path, int line) : path_(path), line_(line) { } void __cdecl operator()(const char *fmt, ...) const { va_list ptr; va_start(ptr, fmt); char buffer[4096] = {0}; std::string filename(path_); int ipos = filename.find_last_of('\\'); filename = filename.substr(ipos+1, filename.size()-ipos+1); int iret = sprintf_s(buffer, sizeof(buffer), "[%s, %d] ", filename.c_str(), line_); if (-1 != iret) { vsnprintf_s(buffer+iret, sizeof(buffer)-iret-1, _TRUNCATE, fmt, ptr); udp_.send(buffer); } va_end(ptr); }private: const char *path_; const int line_; static CUdpClient udp_;};CUdpClient CTrace::udp_;///////////////////////////////////////测试代码/////////////////////////////////////////////// 产生随机字符串std::string BuildRandString(int num){ static unsigned int s_add = 0; std::string ret; srand((unsigned int)time(NULL) + (s_add++)); for (int i=0; i<num; ) { char buf[17] = {0}; _itoa_s(rand(), buf, 0x10); ret += buf; i += strlen(buf); } return ret.substr(0, num);}int _tmain(int argc, _TCHAR* argv[]){ WSADATA wsa; int iret = WSAStartup(MAKEWORD(2, 2), &wsa); if (0 != iret) { return 0; } int num = 0; while (1) { char c = getchar(); // 每按下一个按键产生一条日志 std::string str = BuildRandString(100); Trace("%d, %s", ++num, str.c_str()); // 用法 } WSACleanup(); system("pause"); return 0;}服务端使用WTL做了个简单的单文档list box形式的界面用来展现
WTL库安装下载地址:http://www.cnblogs.com/tujiaw/archive/2011/02/26/3059245.html
首先在对话框创建的时候初始化socket,创建接收数据线程
WSADATA wsa; WSAStartup(MAKEWORD(2, 2), &wsa); InitSocket(); m_threadHandle = (HANDLE)_beginthreadex(NULL, 0, RecvData, this, 0, NULL); CloseHandle(m_threadHandle);
void InitSocket() { sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY); sin.sin_port = htons(5050); m_sock = socket(AF_INET, SOCK_DGRAM, 0); if (INVALID_SOCKET != m_sock) { if (SOCKET_ERROR == bind(m_sock, (SOCKADDR*)&sin, sizeof(sin))) { closesocket(m_sock); } } }线程不断的接收数据并显示到界面上
unsigned int __stdcall RecvData(void* arg){ CMainFrame *p = (CMainFrame*)arg; if (NULL == p) { return 0; } sockaddr_in clientAddr; int clientLen = sizeof(clientAddr); while(g_isRunning) { if (INVALID_SOCKET == p->m_sock) { break; } char buffer[4096] = {0}; if (recvfrom(p->m_sock, buffer, sizeof(buffer), 0, (sockaddr*)&clientAddr, &clientLen) > 0) { p->m_view.AddString(buffer); p->m_view.PostMessageA(WM_VSCROLL, SB_BOTTOM); } } return 0;}
双击单行可以将日志拷贝到剪切板上
LRESULT OnLButtonDClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { char buffer[4096] = {0}; int curSel = GetCurSel(); int len = GetText(curSel, buffer); BOOL bret = OpenClipboard(); EmptyClipboard(); HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, len + 1); char *p = (char*)GlobalLock(hGlobal); memset(p, 0, len+1); memcpy(p, buffer, strlen(buffer)); bret = GlobalUnlock(hGlobal); HANDLE hResult = SetClipboardData(CF_TEXT, hGlobal); if (hResult) { memset(buffer, 0, sizeof(buffer)); sprintf_s(buffer, "拷贝数据到剪切板成功,长度:%d", len); MessageBox(buffer); } CloseClipboard(); return 0; }
源码是用vs2012编译的,只需要关注MainFrm.h文件就可以了,拷贝数据到剪切板代码在ShowTraceView.h中
下载地址:http://files.cnblogs.com/tujiaw/ShowTrace.rar
- 简单UDP日志程序
- 简单UDP程序
- 简单的TCP/UDP程序
- UDP实现简单聊天程序
- 基于UDP简单聊天程序
- 最简单的UDP程序
- 最简单的UDP程序
- 一个简单的 UDP网络程序
- 一个简单的UDP广播程序
- UDP通信的简单实现(程序)
- 基于UDP的简单聊天程序
- udp服务器_简单的控制台程序
- 非常简单的UDP通信程序,C#
- c++通信---最简单的UDP程序
- 网络编程-UDP协议---简单聊天室程序
- java中UDP简单聊天程序
- 基于UDP的简单聊天程序
- Linux下UDP简单通信程序
- vmware9 安装centOS5.4 并连接internet
- Spring面向切面编程
- 管理不同类型的回调函数
- 实验室的一段Python脚本,根据用户指定路径来备份文件
- iOS如何实现表格的折叠效果?
- 简单UDP日志程序
- android手势识别
- C++ 与 字符编码格式
- Fedora 17 无法播放mp3 rmvb
- Megaco/H.248, MGCP
- LOG4CXX编译,使用,简单封装
- 一图搞定各种Join连接
- C++main函数argc和argv命令行参数
- C语言随机函数应用