代码拉取完成,页面将自动刷新
#pragma once
#include <iostream>
#include <string>
#include "Log.hpp"
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdio>
#define SIZE 1024
class UdpServer
{
public:
UdpServer(uint16_t port, std::string ip = "")
: _port(port), _ip(ip), _sockfd(-1)
{
}
~UdpServer()
{
if (_sockfd >= 0)
close(_sockfd);
}
bool initServer()
{
// 1. 创建套接字
_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (_sockfd < 0)
{
logMessage(FATAL, "%d:%s", errno, strerror(errno));
exit(2);
}
logMessage(DEBUG, "%s: %d", "create socket success, sockfd", _sockfd);
// 2. 绑定:将用户设置的IP和PORT在内核中与当前进程强关联
// 2.1 填充属性
struct sockaddr_in local;
bzero(&local, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(_port);
local.sin_addr.s_addr = _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());
if (bind(_sockfd, (struct sockaddr *)&(local), sizeof(local)) < 0)
{
logMessage(FATAL, "bind():errno:%d:%s", errno, strerror(errno));
exit(2);
}
logMessage(NORMAL, "initialize udp server...%s", strerror(errno));
return true;
}
void Start()
{
char buffer[SIZE]; // 用来存放读取的数据
char result[256]; // 保存处理结果
std::string cmd; // 保存命令, 用于回写
for (;;)
{
memset(buffer, 0, sizeof(buffer));
memset(result, 0, sizeof(result));
struct sockaddr_in peer; // 客户端属性集合[输出型参数]
bzero(&peer, sizeof(peer)); // 初始化空间
socklen_t len = sizeof(peer);
// 1. 读取数据
ssize_t s = recvfrom(_sockfd, buffer, sizeof(buffer), 0,
(struct sockaddr *)&peer, &len);
// 2. 处理数据:提取缓冲区中的命令
if (s > 0)
{
buffer[s] = '\0';
FILE *fp = popen(buffer, "r");
if (fp == nullptr) // 读取失败
{
logMessage(ERROR, "popen: %d:%s", errno, strerror(errno));
continue; // 继续读取
}
// 过滤非法指令
if (strcasestr(buffer, "rm") != nullptr || strcasestr(buffer, "rmdir") != nullptr)
{
std::string err_msg = "非法指令: rm/rmdir...";
std::cout << err_msg << buffer << std::endl;
sendto(_sockfd, err_msg.c_str(), err_msg.size(), 0,
(struct sockaddr *)&peer, len);
}
while (fgets(result, sizeof(result), fp) != nullptr)
{
cmd += result;
}
pclose(fp);
}
// 3. 写回数据
sendto(_sockfd, cmd.c_str(), cmd.size(), 0,
(struct sockaddr *)&peer, len);
}
}
private:
uint16_t _port; // 端口号
std::string _ip; // IP地址
int _sockfd; // 套接字文件描述符
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。