96SEO 2026-02-19 18:23 0
远程控制主机基本功能演示通信过程代码实现服务器模块执行命令模块popen系列函数

但是为了防止客户端恶意破坏服务器我们必须创建一个配置文件只有在这个配置文件里的命令客户端才能执行。
服务器端创建监听套接字监听客户端等待客户端连接。
客户端发起连接请求。
连接成功开始通信。
客户端发送命令。
服务器端接收到命令并创建一个新线程线程在线程调用的函数中设置为分离状态主线程不需要对子线程等待。
新线程执行一系列函数后给客户端返回执行结果。
inet_ntoa(addr.addr().sin_addr),
ntohs(addr.addr().sin_port));while
arg){pthread_detach(pthread_self());
-1){perror(accept);break;}InetAddr
};执行命令的函数在外面传入类中当新线程接收数据后回调这个函数处理任务创建子进程处理执行命令并返回数据。
LoadCommandSet()//加载安全命令集合{ifstream
ios::in);//打开文件以读取的方式if(!infile.is_open())//判断文件是否打开成功{LOG(FATAL,
line))//读取文件中的安全命令{_CommandSet.insert(line);//插入到安全命令集合中}infile.close();//关闭文件}bool
Command)//判断是否是安全命令{if(Command.empty())//判断命令是否为空{return
Command.find(seq);//找到空格的位置string
pos);//提取核心命令//判断是否在安全命令集合中if(_CommandSet.find(core)
_CommandSet.end())//在安全命令集合中{return
commandpath):_cond_path(path){LoadCommandSet();//加载安全命令集合}string
dup2//这些都可以通过库函数popen来实现//(这个函数是一个标准库函数用于创建一个管道然后调用fork产生一个子进程然后调用exec执行一个命令)
if(!IsSecure(Command))//判断是否是安全命令{LOG(WARNING,
nullptr)//判断是否执行成功{LOG(WARNING,
{0};//定义一个缓冲区while(fgets(output,
output;}pclose(fp);//关闭文件return
执行命令不能在子线程中执行命令因为子线程还要接收来自某个客户端的数据所有应该子线程创建一个子进程调用exec系列的函数执行命令。
返回数据进程之间具有独立性我们选择使用匿名管道进行进程间通信。
安全的命令可以通过创建一个配置文件然后创建命令对象时将配置文件加载进集合文件IO慢如果命令前缀在集合中就执行反之直接返回提示信息。
上述两个步骤都不需要我们自己去实现C语言库中提供了一个这样的函数可以帮我们完成上述功能我们来介绍这个函数
库函数提供了一种简单的方式来创建一个管道pipe并启动一个子进程以执行外部命令。
popen
socket(AF_INET,SOCK_STREAM,0);//创建套接字if(sockfd
1;}//客户端需要bind,但是不需要我们显示的bind//客户端也不需要listen监听请求是服务器程序的工作struct
htons(port);inet_pton(AF_INET,ip.c_str(),addr.sin_addr.s_addr);if(connect(sockfd,(struct
message:;getline(cin,message);//获取用户输入的信息,一行一行的获取send(sockfd,message.c_str(),message.size()1,0);char
buffer[1024];memset(buffer,0,sizeof(buffer));int
recv(sockfd,buffer,sizeof(buffer),0);if(n
服务器主程序将命令处理函数bind并传给服务器类的成员以供子线程调用该方法。
打印程序的命令行使用格式提示用户输入端口号exit(USAGEERROR);
将命令行参数转为端口号uint16_t类型这是服务器监听的端口号uint16_t
创建TcpServer对象并初始化unique_ptrTcpServer
make_uniqueTcpServer(port,std::bind(ExecuteCommand::Execute,ExecuteCommand()
使用从命令行获得的端口号创建TcpServer实例server-InitServer();
我们修改一下客户端的echo代码即可windows中的网络库与Linux上的有一些差异在Udp通信的时候已经介绍过了
创建套接字使用IPv4地址族和TCP协议SOCK_STREAM表示流式套接字int
sockaddr_in结构体用于存储服务器的网络地址addr.sin_family
设置服务器的端口号htons将端口号转换为网络字节序inet_pton(AF_INET,
如果连接失败输出错误信息closesocket(sockfd);WSACleanup();return
关闭套接字结束与服务器的通信closesocket(sockfd);
编译器MSVC的扩展指令它的功能和gcc/g中的-l选项类似可以告诉编译器要链接的库的名称。
C是由微软开发的一款集成开发环境IDE和编译器工具套件用于开发基于
状态机是一种用于描述系统行为数学模型它的核心是状态它通过定义不同的状态让系统执行不同的操作且执行这些操作时得到的结果会更新状态。
IP端口最大重连次数和重连间隔Clientconnect(int16_t
std::endl;exit(Exitcode::SOCKETERR);}struct
std::endl;exit(Exitcode::INET_PTONERR);}//
std::endl;break;}sleep(_interval);
初始状态尝试连接_connect.Connect();break;case
已连接状态处理数据_connect.Process();break;case
连接失败尝试重连_connect.Reconnect();break;case
已关闭退出_connect.Close();return;default:break;}}}~Client()
std::endl;exit(Exitcode::USAGEERR);
NEW初始状态处于这个状态的客户端还未尝试连接服务器。
CONNECTED连接服务器成功处于这个状态的客户端即将开始IO通信。
CONNECTING正在连接服务器的状态这个状态一般是瞬时状态发生在开始连接了但是还未连接成功。
DISCONNECTED连接失败的状态处于这个状态的服务器将会开始重连逻辑。
CLOSED客户端套接字关闭一般发生在重连失败后。
我们编译客户端程序并在本地云服务器创建一个具有echo功能的服务器程序测试如下情况
一开始连接是成功的服务器和客户端可以正常的通信。
但是服务器不再运行后客户端又开始重连未达到重连次数时又运行起服务器就可以重连成功。
否则重连失败。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback