Android实现远程控制PC(Android[客户端]+Qt[服务器端])

由于本人没有无线路由器,因此用Win7自带的虚拟wifi让手机上网:Win7虚拟wifi

但是,电脑不在我的房间,因此每天晚上在床上玩完手机还要下床去关电脑,让很懒很懒的本人很不爽,因此自己尝试着做了一个远程控制。

软件客户端运行在Android设备上(我的手机是Android的),服务器端运行在我的Win7本本上。客户端用的是Android平台应用编程,服务器端用的是Qt编写的。

首先设置好默认端口,然后设置控制方法,为了方便起见,这里直接利用标准C中的system接口(调用shell,Win7下就是cmd命令提示符了)。客户端发送命令给服务器,服务器直接执行命令,并将标准输出返回给客户端。

下面看一些代码,具体代码可以到这里下载:工程源代码

服务器端:

头文件:

mainwindow.h

[cpp] view plain copy

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QtNetwork/QTcpServer>
  5. #include <QTextDocument>
  6. #include "server.h"
  7. namespace Ui {
  8. class MainWindow;
  9. }
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit MainWindow(QWidget *parent = 0);
  15. QTextDocument *textDocument;
  16. Server *server;
  17. ~MainWindow();
  18. public slots:
  19. void getConnect();
  20. void execCommand(const char *command,int length,const char *add,int clientCode);
  21. void showText(const char *text);
  22. signals:
  23. void writeFile(int clientCode);
  24. private:
  25. Ui::MainWindow *ui;
  26. };
  27. #endif // MAINWINDOW_H

server.h

[cpp] view plain copy

  1. #ifndef SERVER_H
  2. #define SERVER_H
  3. #include <QTextDocument>
  4. #include <QTcpServer>
  5. class MainWindow;
  6. class Server:public QTcpServer
  7. {
  8. Q_OBJECT
  9. private:
  10. int port;
  11. MainWindow *mainWindow;
  12. QHostAddress hostAddress;
  13. int clientNum;        //已建立的客户端连接数
  14. public:
  15. Server(MainWindow *m,int p,QHostAddress a);
  16. void incomingConnection(int handle);
  17. signals:
  18. void printText(const char *text);
  19. };
  20. #endif // SERVER_H

serverthread.h

[cpp] view plain copy

  1. #ifndef SERVERTHREAD_H
  2. #define SERVERTHREAD_H
  3. #include <QThread>
  4. #include <QTcpSocket>
  5. #include "mainwindow.h"
  6. class ServerThread:public QThread
  7. {
  8. Q_OBJECT
  9. private:
  10. QTcpSocket *socket;
  11. MainWindow *mainWindow;
  12. int clientCode;
  13. public:
  14. ServerThread(int socketDescriptor,QObject *parent,MainWindow *m,int clientCode);
  15. void run();
  16. signals:
  17. void newCommand(const char *str,const int length,const char *add,int clientCode);
  18. public slots:
  19. void receiveData();
  20. void readFile(int cC);
  21. };
  22. #endif // SERVERTHREAD_H

源代码:

main.cpp

[cpp] view plain copy

  1. #include <QtGui/QApplication>
  2. #include "mainwindow.h"
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. MainWindow w;
  7. w.show();
  8. return a.exec();
  9. }

mainwindow.cpp

[cpp] view plain copy

  1. #include <QtNetwork/QHostAddress>
  2. #include <QTextDocument>
  3. #include <string>
  4. #include <cstring>
  5. #include <string.h>
  6. #include "mainwindow.h"
  7. #include "ui_mainwindow.h"
  8. MainWindow::MainWindow(QWidget *parent) :
  9. QMainWindow(parent),
  10. ui(new Ui::MainWindow)
  11. {
  12. ui->setupUi(this);
  13. server=new Server(this,5648,QHostAddress::Any);   //初始化服务器
  14. }
  15. MainWindow::~MainWindow()
  16. {
  17. delete ui;
  18. }
  19. void MainWindow::getConnect()
  20. {
  21. QTextDocument *textDocumentM=new QTextDocument(QString("new connect !"),this);
  22. ui->textEdit->setDocument(textDocumentM);
  23. server->nextPendingConnection();
  24. }
  25. void MainWindow::execCommand(const char *command,int length,const char *add, int clientCode)
  26. {
  27. QTextDocument *textDocumentC=new QTextDocument(QString("message"),this);
  28. char *commandStr=new char[length+15];
  29. strcpy(commandStr,command);
  30. char *para=commandStr+length;
  31. char *c=" > temp.txt";        //将结果重定向到一个临时文件
  32. strcpy(para,c);
  33. system(commandStr);                        //执行shell命令
  34. emit writeFile(clientCode);
  35. ui->textEdit->setDocument(textDocumentC);
  36. }
  37. void MainWindow::showText(const char *text)
  38. {
  39. QTextDocument *textDocumentT=new QTextDocument(QString(text),this);
  40. ui->textEdit->setDocument(textDocumentT);
  41. }

server.cpp

[cpp] view plain copy

  1. #include "server.h"
  2. #include "serverthread.h"
  3. Server::Server(MainWindow *m,int p,QHostAddress a)
  4. {
  5. this->hostAddress=a;
  6. this->port=p;
  7. this->mainWindow=m;
  8. this->clientNum=0;             //初始化客户连接数
  9. this->QTcpServer::listen(hostAddress,quint16(port));
  10. connect(this,SIGNAL(printText(const char*)),this->mainWindow,SLOT(showText(const char*)));
  11. }
  12. void Server::incomingConnection(int handle)
  13. {
  14. char ch[]="new connection !";
  15. emit printText(ch);
  16. ServerThread *thread=new ServerThread(handle,this,mainWindow,this->clientNum);  //每建立一个连接,都会开启一个服务线程,线程有客户编号
  17. this->clientNum++;
  18. thread->start();
  19. }

serverthread.cpp

[cpp] view plain copy

  1. #include "serverthread.h"
  2. #include <QFile>
  3. #define COMMAND_SIZE 50
  4. ServerThread::ServerThread(int socketDescriptor,QObject *parent,MainWindow *m,int c):QThread(parent)
  5. {
  6. this->mainWindow=m;
  7. this->clientCode=c;
  8. socket=new QTcpSocket(parent);
  9. socket->setSocketDescriptor(socketDescriptor);
  10. }
  11. void ServerThread::run()
  12. {
  13. this->connect(socket,SIGNAL(readyRead()),this,SLOT(receiveData()));
  14. connect(this,SIGNAL(newCommand(const char*,int,const char*,int)),this->mainWindow,SLOT(execCommand(const char*,int,const char*,int)));
  15. connect(this->mainWindow,SIGNAL(writeFile(int)),this,SLOT(readFile(int)));
  16. exec();
  17. }
  18. void ServerThread::receiveData()
  19. {
  20. int left=socket->bytesAvailable();
  21. char *command=new char[COMMAND_SIZE];
  22. while(left>0)
  23. {
  24. int read=socket->readLine(command,COMMAND_SIZE);  //读取原始命令
  25. emit newCommand(command,read,"test",this->clientCode);
  26. left-=read;
  27. }
  28. }
  29. //读取临时文件中的标准输出信息并写入socket传回给客户端
  30. void ServerThread::readFile(int cC)
  31. {
  32. if(cC==this->clientCode)
  33. {
  34. QFile *file=new QFile("temp.txt");
  35. if(file->open(QIODevice::ReadWrite))
  36. {
  37. char *buffer=new char[100];
  38. int length;
  39. while((length=file->read(buffer,100))>0)
  40. {
  41. socket->write(buffer,length);
  42. }
  43. }
  44. socket->flush();
  45. file->close();
  46. system("del temp.txt");//删除临时文件
  47. }
  48. }

客户端:

只有一个Acitvity

MainActivity.Java

[java] view plain copy

  1. package com.tobacco.phonetest;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.Socket;
  7. import java.net.UnknownHostException;
  8. import android.app.Activity;
  9. import android.os.Bundle;
  10. import android.os.Handler;
  11. import android.util.Log;
  12. import android.view.Menu;
  13. import android.view.View;
  14. import android.view.View.OnClickListener;
  15. import android.widget.Button;
  16. import android.widget.EditText;
  17. import android.widget.TextView;
  18. public class MainActivity extends Activity implements OnClickListener,Runnable{
  19. private Button button;
  20. private Button clear;
  21. private EditText editText;
  22. private TextView tv;
  23. private Socket socket;
  24. private PrintWriter pw;
  25. private BufferedReader br;
  26. //private InputStream is;
  27. private Handler handler;
  28. @Override
  29. public void onCreate(Bundle savedInstanceState) {
  30. super.onCreate(savedInstanceState);
  31. setContentView(R.layout.activity_main);
  32. handler=new Handler();
  33. button=(Button)findViewById(R.id.button);
  34. clear=(Button)findViewById(R.id.clear);
  35. button.setOnClickListener(this);
  36. clear.setOnClickListener(this);
  37. editText=(EditText)findViewById(R.id.edittext);
  38. tv=(TextView)findViewById(R.id.textView);
  39. try {
  40. //socket=new Socket("tobacco5648.xicp.net",5648); //我的pc域名
  41. socket=new Socket("192.168.137.1",5648);   //建立socket,这里应该根据pc的ip地址进行修改
  42. //socket=new Socket("www.baidu.com",80);
  43. } catch (UnknownHostException e) {
  44. // TODO Auto-generated catch block
  45. e.printStackTrace();
  46. Log.e("socket","unknown host");
  47. } catch (IOException e) {
  48. // TODO Auto-generated catch block
  49. e.printStackTrace();
  50. Log.e("socket","io execption");
  51. }
  52. if(socket==null){
  53. Log.e("socket","null");
  54. }
  55. else
  56. try {
  57. pw=new PrintWriter(socket.getOutputStream());
  58. br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"gbk"));
  59. String remote=socket.getInetAddress().getHostAddress();
  60. String self=socket.getLocalAddress().getHostAddress();
  61. tv.setText("connected!"+"\r\n"+"remote:"+remote+"\r\n"+"local:"+self+"\r\n");
  62. //is=socket.getInputStream();
  63. if(pw!=null&&br!=null){
  64. new Thread(this).start();
  65. }
  66. } catch (IOException e) {
  67. // TODO Auto-generated catch block
  68. e.printStackTrace();
  69. }
  70. }
  71. @Override
  72. public boolean onCreateOptionsMenu(Menu menu) {
  73. getMenuInflater().inflate(R.menu.activity_main, menu);
  74. return true;
  75. }
  76. public void onClick(View view) {
  77. if(view==button){
  78. String str;
  79. str=editText.getText().toString();
  80. pw.print(str);
  81. pw.flush();
  82. }
  83. else if(clear==view){
  84. tv.setText("");
  85. }
  86. }
  87. public void run() {
  88. while(true){
  89. try {
  90. String str;
  91. while((str=br.readLine())!=null){
  92. final String s=str;
  93. handler.post(new Runnable(){
  94. public void run() {
  95. tv.setText(tv.getText()+s+"\r\n");
  96. }});
  97. }
  98. } catch (IOException e) {
  99. // TODO Auto-generated catch block
  100. e.printStackTrace();
  101. }
  102. }
  103. }
  104. }

http://blog.csdn.net/tobacco5648/article/details/7780385

时间: 2024-08-11 03:33:03

Android实现远程控制PC(Android[客户端]+Qt[服务器端])的相关文章

我的Android进阶之旅------&gt;Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端

因为经常开着笔记本工作,累了就坐床上玩手机,但晚上要睡觉了又不想下床去关电脑,就想做个Android软件来控制PC端的关机和重启.要想实现此功能,就得让Android手机和PC之间进行通信才能,因此采用Socket编程来实现. ==================================Shutdown命令的用法======================================== 首先得了解一下关于Shutdown命令的用法. 选择win+R,打开命令行窗口,输入shutdo

Android中客户端请求服务器端的方式讲解(一)附源码

Android中客户端请求服务器端的两种方式:Post方式和Get方式 在这里不直接赘述了,直接上源码如下: (1).Post的方式: /** * Post的请求方式 * * @param model * 请求序号 * @param paramList * 客户端请求的数据参数列表 * @return */ public JSONObject doPost(int model, List<NameValuePair> paramList) { try { // 客户端向服务器发送请求的数据 L

android客户端向服务器端验证登陆方法的实现1

遇到的问题:一个条件查询与多个条件查询,所用到的方式不一样 参考文档: http://www.oschina.net/question/1160609_133366    mybatis多条件查询的一个错误 解决方案如下: 利用序列号的方式解决多个参数的查询问题.对象与数据库关系的映射层. 层次结构如下: 首先定义model层里面的Userlist类,这是和我们后台mysql里面的表是一一对应的,然后定义UserlistMapper类,这个类主要是用来封装一些个方法,比如说增删改查等.其实现通过

Android客户端和服务器端数据交互

网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍一下代码最简单.逻辑最清晰的交互例子: 一.服务器端: 二.Android手机客户端:

android客户端向服务器端验证登陆方法的实现2

一.在上一篇文章中,我只是提到了其中一种方法来实现登陆 大家可以参见: http://www.apkbus.com/android-45004-1-1.html      android获取web服务器端session并验证登陆 http://blog.csdn.net/cainiao123hack/article/details/8255848   服务器端向Android客户端传值--登录实现 http://zhidao.baidu.com/link?url=8g9EWhyUkUgUr1dh

Android项目之无线点餐(2)--用户登录的客户端和服务器端实现

一.服务器端实现 (1)创建动态服务器项目 个部分代码如下: package com.lc.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class ConnectionUtil { /** * 打开连接 * * @return */ public static Connection open() { // 1.url // 2.driver

Android客户端请求服务器端的详细解释

Android客户端请求服务器端的详细解释 1. Android客户端与服务器端通信方式: Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式. 2. 解析服务器端返回数据的解释: (1).对于服务器端来说,返回给客户端的数据格式一般分为html.xml和json这三种格式. (2). JSON(Javascript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比

Android客户端与服务器端通过DES加密认证

转载地址:http://blog.csdn.net/spring21st/article/details/6730283 由于Android应用没有像web开发中的session机制,所以采用PHPSESSID的方式,是没有办法获取客户端登录状态的. 这种情况下,如何在用户登录后,服务器端获取用户登录状态并保持,就必须采用一种“握手”的方式. 每个手机都有自己的IMEI号,那么能不能通过这个标识去做认证呢? 经过试验,答案是可以! 客户端在请求服务器端的时候,请求参数为 IMEI (param

Android 客户端与服务器端进行数据交互(二、登录客户端)

概要 Android客户端分为User,HttpUtil,HttpCallbackListener,MainActivity四个部分.User model与服务端的一样,一方面是用于本地用户信息的存储model,另一方面也是为了保证构造URL时使用的key一致. HttpUtil封装了发送Http请求的过程和构造URL的函数,HttpCallbackListener是用于发送请求后的回调接口,MainActivity就是用于测试的Activity交互界面了. User model 不再贴出,见上