从入门到入土:基于C语言采用TCP协议实现远程控制|详细说明|利用流套接字实现一个简单的远程控制系统

此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出。欢迎各位前来交流。(部分材料来源网络,若有侵权,立即删除)
本人博客所有文章纯属学习之用,不涉及商业利益。不合适引用,自当删除!
若被用于非法行为,与我本人无关

基于C语言采用TCP协议实现远程控制|详细说明|利用流套接字实现一个简单的远程控制系统

讲解

远程控制系统

  • 客户端接收用户输入的命令,客户端通过套接字将命令传送给服务器端,
  • 服务器在收到用户的命令,对命令进行解析
  • 在服务器端调用对应的命令
  • 并将命令执行的结果发送给客户端,从而实现远距离控制的功能
  • 注:远程控制系统、木马、僵尸程序都属于远程控制类程序

工作原理

  • List item

原理讲解

  • TCP套接字编程

在这里插入图片描述

  • 无连接的服务
    在这里插入图片描述
  • 流程图
    在这里插入图片描述

客户端代码分析

  • 定义变量
#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define BUF_SIZE 2048
#define PORT 8900
int main(int argc,char** argv)
{
	struct sockaddr_in server;
	int ret;
	int len;
	int port;
	int sockfd;
	int sendnum;
	int recvnum;
	char send_buf[BUF_SIZE];
	char recv_buf[BUF_SIZE];

    port=PORT;
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);
  • 建立套接字
 port=PORT;
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);

    if (-1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))
	{
		perror("can not create socket\n");
		exit(1);
	}
  • 将服务器的IP地址和端口号赋给套接字
memset(&server,0,sizeof(struct sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(argv[1]);
	server.sin_port = htons(port);
  • 和服务器建立连接
	if (0>(ret=connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr))))
	{
		perror("connect error");
		close(sockfd);
		exit(1);
	}
  • 进入循环
	while(1)
{
		memset(send_buf,0,2048);
		memset(recv_buf,0,2048);
		
		printf("tcp>");
		gets(send_buf);
		printf("\n");
		len = sizeof(struct sockaddr);
  • 收到quit命令退出
if (0>(len=send(sockfd,send_buf,strlen(send_buf),0)))
		{
			perror("error occar in sending data\n");
			break;

		}
		if (0==strcmp(send_buf,"quit"))
		{
			perror("quitting remote ctroling\n");
			break;
		}
  • 接收服务器端信息并打印,以及服务器宕机情况说明
if (0>(recvnum=recv(sockfd,recv_buf,2048,0)))
		{
			perror("recv data error\n");
			break;
		}
		if(recvnum==0){
			perror("server is done!\n");
			exit(0); 
		}
		fprintf(stdout,"%s\n",recv_buf); 
		
	}
  • 结束循环,退出
	close(sockfd);
	exit(1);
	
}

服务端代码分析

  • 定义变量
#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define PORT 8900

int main(int argc,char** argv)
{
	struct sockaddr_in server;
	struct sockaddr_in client;
	int len;
	int port;
	int listend;
	int connectd;
	int sendnum;
	int opt;
	int recvnum;
	char send_buf[2048];
	char recv_buf[2048];
	char cmd[2048];
	int flag;

      //if (2==argc)

	
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);
  • 建立套接字listend
 if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
      {
	 	perror("create listen socket error\n");
	 	exit(1);
      }
  • 赋给IP和端口
port=PORT;
     memset(&server,0,sizeof(struct sockaddr_in));
     server.sin_family = AF_INET;
     server.sin_addr.s_addr = htonl(INADDR_ANY);
     server.sin_port = htons(port);
  • 绑定套接字与监听
 if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
     {
		perror("bind error\n");
		exit(1);

     }

    if (-1==listen(listend,5))
    {
		perror("listen error\n");
		exit(1);
    }
  • 第一层循环
 while (1)
    {
    

        if (-1==(connectd=accept(listend,(struct sockaddr*)&client,&len)))

    	{
		perror("create connect socket error\n");
		continue;
    	}
  • 第二层循环,并且判断客户端是否断开
while(1)
    {
    	memset(recv_buf,0,2048);
    	memset(send_buf,0,2048);
		
		if(0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
		{
			perror("recv error\n");
			close(connectd);
			continue;
		}
		if(recvnum==0){
			close(connectd);
			break;
		}
  • 存储接收到的命令
if(1)
		{
		recv_buf[recvnum]='\0';
		if (0==strcmp(recv_buf,"quit"))
		{
			perror("quitting remote controling\n");
			exit(1);

		}
		printf("the message is: %s\n",recv_buf);
		strcpy(cmd,"/bin/");
		strcat(cmd,recv_buf);
		execute(cmd,send_buf);
		if ('\0'==*send_buf)
		{
			memset(cmd,0,sizeof(cmd));
			strcpy(cmd,"/sbin/");
			strcat(cmd,recv_buf);
			execute(cmd,send_buf);
			
			if ('\0'==*send_buf)
			{	
				memset(cmd,0,sizeof(cmd));
				strcpy(cmd,"/usr/bin/");
				strcat(cmd,recv_buf);
				execute(cmd,send_buf);
			}
			
			if ('\0'==*send_buf)
			{	
				memset(cmd,0,sizeof(cmd));
				strcpy(cmd,"/usr/sbin/");
				strcat(cmd,recv_buf);
				execute(cmd,send_buf);
			}
		}
		if ('\0'==*send_buf)
			sprintf(send_buf,"command is not vaild,check it please\n");
		printf("the server message is:%s\n",send_buf);
	}
  • 发送返回结果并依次跳出两轮循环
if (0>send(connectd,send_buf,sizeof(send_buf),0))
		{
			perror("send error\n");
			close(connectd);
			continue;
		}
		}
		close(connectd);
		continue;
}

	close(listend);
	return 0;


}
  • cmd执行函数
int execute(char* command,char* buf)
{
	FILE * 	fp;
	int count;
	
	if (NULL==(fp = popen(command,"r")))
	{
		perror("creating pipe error\n");
		exit(1);

	}
	
	count = 0 ;

	while(((buf[count] = fgetc(fp))!=EOF)&&count<2047)
	count++;
	buf[count]='\0';

	pclose(fp);
	return count;
	

} 

运行结果

  • 编译:

在这里插入图片描述

  • 验证在客户端进行ctrl+c多次退出后服务器不受影响
    在这里插入图片描述

  • 验证可以通过客户端对服务器进行cmd命令操作,实现了远程操作
    在这里插入图片描述
    在这里插入图片描述

  • 关闭服务器的情况下,会返回结果并且结束客户端进程
    在这里插入图片描述

  • 输入错误命令会有报错展示
    在这里插入图片描述

代码

客户端

#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define BUF_SIZE 2048
#define PORT 8900

int main(int argc,char** argv)
{
	struct sockaddr_in server;
	int ret;
	int len;
	int port;
	int sockfd;
	int sendnum;
	int recvnum;
	char send_buf[BUF_SIZE];
	char recv_buf[BUF_SIZE];

    port=PORT;
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);

    if (-1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))
	{
		perror("can not create socket\n");
		exit(1);
	}


	memset(&server,0,sizeof(struct sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(argv[1]);
	server.sin_port = htons(port);


	if (0>(ret=connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr))))
	{
		perror("connect error");
		close(sockfd);
		exit(1);

	}

	while(1)
{
		memset(send_buf,0,2048);
		memset(recv_buf,0,2048);
		
		printf("tcp>");
		gets(send_buf);
		printf("\n");
		len = sizeof(struct sockaddr);
		if (0>(len=send(sockfd,send_buf,strlen(send_buf),0)))
		{
			perror("error occar in sending data\n");
			break;

		}
		if (0==strcmp(send_buf,"quit"))
		{
			perror("quitting remote ctroling\n");
			break;
		}
	
		if (0>(recvnum=recv(sockfd,recv_buf,2048,0)))
		{
			perror("recv data error\n");
			break;
		}
		if(recvnum==0){
			perror("server is done!\n");
			exit(0); 
		}
		fprintf(stdout,"%s\n",recv_buf); 
		
	}
	close(sockfd);
	exit(1);
	
}

服务端

#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define PORT 8900

int main(int argc,char** argv)
{
	struct sockaddr_in server;
	struct sockaddr_in client;
	int len;
	int port;
	int listend;
	int connectd;
	int sendnum;
	int opt;
	int recvnum;
	char send_buf[2048];
	char recv_buf[2048];
	char cmd[2048];
	int flag;

      //if (2==argc)

	
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);
	
      
      

      if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
      {
	 	perror("create listen socket error\n");
	 	exit(1);
      }
      
    port=PORT;
     memset(&server,0,sizeof(struct sockaddr_in));
     server.sin_family = AF_INET;
     server.sin_addr.s_addr = htonl(INADDR_ANY);
     server.sin_port = htons(port);

     if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
     {
		perror("bind error\n");
		exit(1);

     }

    if (-1==listen(listend,5))
    {
		perror("listen error\n");
		exit(1);
    }

    while (1)
    {
    

        if (-1==(connectd=accept(listend,(struct sockaddr*)&client,&len)))

    	{
		perror("create connect socket error\n");
		continue;
    	}
    	
    	
    	
    while(1)
    {
    	memset(recv_buf,0,2048);
    	memset(send_buf,0,2048);
		
		if(0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
		{
			perror("recv error\n");
			close(connectd);
			continue;
		}
		if(recvnum==0){
			close(connectd);
			break;
		}
		
	if(1)
		{
		recv_buf[recvnum]='\0';
		if (0==strcmp(recv_buf,"quit"))
		{
			perror("quitting remote controling\n");
			exit(1);

		}
		printf("the message is: %s\n",recv_buf);
		strcpy(cmd,"/bin/");
		strcat(cmd,recv_buf);
		execute(cmd,send_buf);
		if ('\0'==*send_buf)
		{
			memset(cmd,0,sizeof(cmd));
			strcpy(cmd,"/sbin/");
			strcat(cmd,recv_buf);
			execute(cmd,send_buf);
			
			if ('\0'==*send_buf)
			{	
				memset(cmd,0,sizeof(cmd));
				strcpy(cmd,"/usr/bin/");
				strcat(cmd,recv_buf);
				execute(cmd,send_buf);
			}
			
			if ('\0'==*send_buf)
			{	
				memset(cmd,0,sizeof(cmd));
				strcpy(cmd,"/usr/sbin/");
				strcat(cmd,recv_buf);
				execute(cmd,send_buf);
			}
		}
		if ('\0'==*send_buf)
			sprintf(send_buf,"command is not vaild,check it please\n");
		printf("the server message is:%s\n",send_buf);
	}
	
	
	if (0>send(connectd,send_buf,sizeof(send_buf),0))
		{
			perror("send error\n");
			close(connectd);
			continue;
		}
		}
		close(connectd);
		continue;
}

	close(listend);
	return 0;


}
	
int execute(char* command,char* buf)
{
	FILE * 	fp;
	int count;
	
	if (NULL==(fp = popen(command,"r")))
	{
		perror("creating pipe error\n");
		exit(1);

	}
	
	count = 0 ;

	while(((buf[count] = fgetc(fp))!=EOF)&&count<2047)
	count++;
	buf[count]='\0';

	pclose(fp);
	return count;
	

} 

end

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Simulink是一款强大的仿真工具,用于设计、模拟和分析各种系统的行为。下面是一个入门入土的Simulink仿真教程。 1. 软件安装:首先需要下载和安装Simulink软件。在MathWorks官方网站上找到适合的版本,并按照指示进行安装。 2. Simulink基础:打开Simulink后,可以看到一个模块化的仿真环境。了解基本的Simulink界面、工具栏和库,这些是使用Simulink进行仿真的基础。 3. 模型建立:使用Simulink可以通过将各种模块组合在一起来建立模型。通过从库中拖拽模块到仿真界面,使用线连接相应的模块,可以构建出一个完整的系统模型。 4. 参数设置:对于每个模块,都可以设置相应的参数。这些参数可根据需要进行调整,以便模型可以更准确地模拟真实系统的行为。 5. 信号输入:创建一个仿真的关键是提供输入信号。可以通过添加信号源模块来生成不同类型的输入信号,如恒定值、正弦波、脉冲等。 6. 仿真运行:配置好模型和输入信号后,可以点击运行按钮开始仿真。仿真结果将在仿真器窗口中显示,此时可以观察系统的行为。 7. 结果分析:Simulink提供了多种工具用于分析仿真结果。可以绘制输出信号的波形图,计算系统的响应时间、频率响应等。 8. 优化改进:根据分析结果,可以调整模型参数以改进系统的性能。这包括调整模块参数、修改模型结构等。 9. 进阶功能:通过进一步学习和实践,还可以掌握更高级的Simulink功能,如使用MATLAB脚本进行仿真、使用状态图进行建模等。 10. 深入学习:要真正掌握Simulink,需要不断深入学习和实践。可以参考Simulink的官方文档、视频教程和论坛,以及阅读相关书籍。 总之,通过上述步骤,您可以从入门入土地掌握Simulink的基本原理和使用方法,能够进行各种系统模型的建立和仿真。但记住,Simulink只是一个工具,对于真正理解和解决复杂系统问题,还需要深入学习掌握相关的系统理论和建模方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值