【探索Linux】—— 强大的命令行工具 P.28(网络编程套接字 —— 简单的UDP网络程序模拟实现)
阅读导航
- 引言
- 一、UDP协议
- 二、UDP网络程序模拟实现
- 1. 预备代码
- ⭕makefile文件
- ⭕打印日志文件
- ⭕打开指定的终端设备文件,并将其作为标准错误输出的目标文件描述符
- 2. UDP 服务器端实现(UdpServer.hpp)
- 3. UDP 客户端实现(main函数)
- 温馨提示
引言
在前一篇文章中,我们详细介绍了UDP协议和TCP协议的特点以及它们之间的异同点。本文将延续上文内容,重点讨论简单的UDP网络程序模拟实现。通过本文的学习,读者将能够深入了解UDP协议的实际应用,并掌握如何编写简单的UDP网络程序。让我们一起深入探讨UDP网络程序的实现细节,为网络编程的学习之旅添上一份精彩的实践经验。
一、UDP协议
UDP(User Datagram Protocol)是一种无连接的、轻量级的网络传输协议,它提供了快速、简单的数据传输服务。下面是一个简单的UDP程序实现示例,包括一个UDP服务器和一个UDP客户端。详介绍可以看上一篇文章:UDP协议介绍 | TCP协议介绍 | UDP 和 TCP 的异同
二、UDP网络程序模拟实现
1. 预备代码
⭕makefile文件
.PHONY:all all:udpserver udpclient udpserver:Main.cc g++ -o $@ $^ -std=c++11 udpclient:UdpClient.cc g++ -o $@ $^ -lpthread -std=c++11 .PHONY:clean clean: rm -f udpserver udpclient
这段代码是一个简单的 Makefile 文件,用于编译 UDP 服务器(udpserver)和 UDP 客户端(udpclient)的程序。在这个 Makefile 中定义了两个规则:
- all:表示默认的目标,依赖于 udpserver 和 udpclient 目标,即执行 make 命令时会编译 udpserver 和 udpclient。
- clean:用于清理生成的可执行文件 udpserver 和 udpclient。
在 Makefile 中使用了一些特殊的关键字和变量:
- .PHONY:声明 all 和 clean 是伪目标,不是真正的文件名。
- $@:表示目标文件名。
- $^:表示所有依赖文件列表。
- -std=c++11:指定 C++ 的编译标准为 C++11。
- -lpthread:链接 pthread 库,用于多线程支持。
⭕打印日志文件
#pragma once #include #include #include #include #include #include #include #include #define SIZE 1024 #define Info 0 #define Debug 1 #define Warning 2 #define Error 3 #define Fatal 4 #define Screen 1 #define Onefile 2 #define Classfile 3 #define LogFile "log.txt" class Log { public: Log() { printMethod = Screen; // 默认输出方式为屏幕打印 path = "./log/"; // 默认日志文件存放路径 } void Enable(int method) { printMethod = method; // 设置日志输出方式(屏幕、单个文件、分类文件) } std::string levelToString(int level) { switch (level) { case Info: return "Info"; case Debug: return "Debug"; case Warning: return "Warning"; case Error: return "Error"; case Fatal: return "Fatal"; default: return "None"; } } void printLog(int level, const std::string &logtxt) { switch (printMethod) { case Screen: std::cout std::string _logname = path + logname; // 构建日志文件的完整路径 int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // 打开文件,如果文件不存在则创建 if (fd tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec); va_list s; va_start(s, format); char rightbuffer[SIZE]; vsnprintf(rightbuffer, sizeof(rightbuffer), format, s); va_end(s); // 格式:默认部分+自定义部分 char logtxt[SIZE * 2]; snprintf(logtxt, sizeof(logtxt), "%s %s", leftbuffer, rightbuffer); printLog(level, logtxt); // 打印日志信息 } private: int printMethod; // 日志输出方式 std::string path; // 日志文件存放路径 };
该代码实现了一个简单的日志记录类(Log),其中包括设置日志输出方式(屏幕、单个文件、分类文件)和打印日志信息的功能。
- Log 类是一个用于记录日志的类。
- Enable 函数用于设置日志输出方式,可以选择屏幕打印、单个文件或分类文件。
- printLog 函数根据设置的日志输出方式,将日志信息打印到屏幕、追加写入单个文件或分类文件。
- printOneFile 函数用于将日志信息追加写入单个文件。
- printClassFile 函数用于将日志信息追加写入分类文件。
- levelToString 函数将日志级别转换为对应的字符串表示。
- operator() 函数是重载的函数调用运算符,用于打印日志信息。
- path 是日志文件存放路径,默认为"./log/"。
- printMethod 是日志输出方式,默认为屏幕打印。
- SIZE 定义了缓冲区大小。
- Info、Debug、Warning、Error、Fatal 是日志级别的定义。
- Screen、Onefile、Classfile 是日志输出方式的定义。
- LogFile 是单个文件名的定义。
⭕打开指定的终端设备文件,并将其作为标准错误输出的目标文件描述符
#include #include #include #include #include #include // 定义要打开的终端设备文件路径 std::string terminal = "/dev/pts/6"; // 打开指定的终端设备文件,并将其作为标准错误输出的目标文件描述符 int OpenTerminal() { // 使用open函数以只写方式打开终端设备文件 int fd = open(terminal.c_str(), O_WRONLY); if(fd
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。