【探索Linux】—— 强大的命令行工具 P.28(网络编程套接字 —— 简单的UDP网络程序模拟实现)

03-25 1064阅读

【探索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 中定义了两个规则:

        1. all:表示默认的目标,依赖于 udpserver 和 udpclient 目标,即执行 make 命令时会编译 udpserver 和 udpclient。
        2. 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 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]