赋料扬雄敌,诗看子建亲。这篇文章主要讲述Android实现远程控制PC(Android[客户端]+Qt[服务器端])相关的知识,希望能为你提供帮助。
由于本人没有无线路由器,因此用Win7自带的虚拟wifi让手机上网:Win7虚拟wifi
但是,电脑不在我的房间,因此每天晚上在床上玩完手机还要下床去关电脑,让很懒很懒的本人很不爽,因此自己尝试着做了一个远程控制。
软件客户端运行在Android设备上(我的手机是android的),服务器端运行在我的Win7本本上。客户端用的是Android平台应用编程,服务器端用的是Qt编写的。
首先设置好默认端口,然后设置控制方法,为了方便起见,这里直接利用标准C中的system接口(调用shell,Win7下就是cmd命令提示符了)。客户端发送命令给服务器,服务器直接执行命令,并将标准输出返回给客户端。
下面看一些代码,具体代码可以到这里下载:工程源代码
服务器端:
头文件:
mainwindow.h
[cpp]
view plain
copy
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include < QMainWindow>
- #include < QtNetwork/QTcpServer>
- #include < QTextDocument>
- #include "server.h"
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = 0);
- QTextDocument *textDocument;
- Server *server;
- ~MainWindow();
- public slots:
- void getConnect();
- void execCommand(const char *command,int length,const char *add,int clientCode);
- void showText(const char *text);
- signals:
- void writeFile(int clientCode);
- private:
- Ui::MainWindow *ui;
- };
- #endif // MAINWINDOW_H
server.h
[cpp] view plain copy
- #ifndef SERVER_H
- #define SERVER_H
- #include < QTextDocument>
- #include < QTcpServer>
- class MainWindow;
- class Server:public QTcpServer
- {
- Q_OBJECT
- private:
- int port;
- MainWindow *mainWindow;
- QHostAddress hostAddress;
- int clientNum; //已建立的客户端连接数
- public:
- Server(MainWindow *m,int p,QHostAddress a);
- void incomingConnection(int handle);
- signals:
- void printText(const char *text);
- };
- #endif // SERVER_H
serverthread.h
[cpp] view plain copy
- #ifndef SERVERTHREAD_H
- #define SERVERTHREAD_H
- #include < QThread>
- #include < QTcpSocket>
- #include "mainwindow.h"
- class ServerThread:public QThread
- {
- Q_OBJECT
- private:
- QTcpSocket *socket;
- MainWindow *mainWindow;
- int clientCode;
- public:
- ServerThread(int socketDescriptor,QObject *parent,MainWindow *m,int clientCode);
- void run();
- signals:
- void newCommand(const char *str,const int length,const char *add,int clientCode);
- public slots:
- void receiveData();
- void readFile(int cC);
- };
- #endif // SERVERTHREAD_H
源代码:
main.cpp
[cpp] view plain copy
- #include < QtGui/QApplication>
- #include "mainwindow.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
mainwindow.cpp
[cpp] view plain copy
- #include < QtNetwork/QHostAddress>
- #include < QTextDocument>
- #include < string>
- #include < cstring>
- #include < string.h>
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui-> setupUi(this);
- server=new Server(this,5648,QHostAddress::Any); //初始化服务器
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::getConnect()
- {
- QTextDocument *textDocumentM=new QTextDocument(QString("new connect !"),this);
- ui-> textEdit-> setDocument(textDocumentM);
- server-> nextPendingConnection();
- }
- void MainWindow::execCommand(const char *command,int length,const char *add, int clientCode)
- {
- QTextDocument *textDocumentC=new QTextDocument(QString("message"),this);
- char *commandStr=new char[length+15];
- strcpy(commandStr,command);
- char *para=commandStr+length;
- char *c=" > temp.txt"; //将结果重定向到一个临时文件
- strcpy(para,c);
- system(commandStr); //执行shell命令
- emit writeFile(clientCode);
- ui-> textEdit-> setDocument(textDocumentC);
- }
- void MainWindow::showText(const char *text)
- {
- QTextDocument *textDocumentT=new QTextDocument(QString(text),this);
- ui-> textEdit-> setDocument(textDocumentT);
- }
server.cpp
[cpp] view plain copy
- #include "server.h"
- #include "serverthread.h"
- Server::Server(MainWindow *m,int p,QHostAddress a)
- {
- this-> hostAddress=a;
- this-> port=p;
- this-> mainWindow=m;
- this-> clientNum=0; //初始化客户连接数
- this-> QTcpServer::listen(hostAddress,quint16(port));
- connect(this,SIGNAL(printText(const char*)),this-> mainWindow,SLOT(showText(const char*)));
- }
- void Server::incomingConnection(int handle)
- {
- char ch[]="new connection !";
- emit printText(ch);
- ServerThread *thread=new ServerThread(handle,this,mainWindow,this-> clientNum); //每建立一个连接,都会开启一个服务线程,线程有客户编号
- this-> clientNum++;
- thread-> start();
- }
serverthread.cpp
[cpp] view plain copy
- #include "serverthread.h"
- #include < QFile>
- #define COMMAND_SIZE 50
- ServerThread::ServerThread(int socketDescriptor,QObject *parent,MainWindow *m,int c):QThread(parent)
- {
- this-> mainWindow=m;
- this-> clientCode=c;
- socket=new QTcpSocket(parent);
- socket-> setSocketDescriptor(socketDescriptor);
- }
- void ServerThread::run()
- {
- this-> connect(socket,SIGNAL(readyRead()),this,SLOT(receiveData()));
- connect(this,SIGNAL(newCommand(const char*,int,const char*,int)),this-> mainWindow,SLOT(execCommand(const char*,int,const char*,int)));
- connect(this-> mainWindow,SIGNAL(writeFile(int)),this,SLOT(readFile(int)));
- exec();
- }
- void ServerThread::receiveData()
- {
- int left=socket-> bytesAvailable();
- char *command=new char[COMMAND_SIZE];
- while(left> 0)
- {
- int read=socket-> readLine(command,COMMAND_SIZE); //读取原始命令
- emit newCommand(command,read,"test",this-> clientCode);
- left-=read;
- }
- }
- //读取临时文件中的标准输出信息并写入socket传回给客户端
- void ServerThread::readFile(int cC)
- {
- if(cC==this-> clientCode)
- {
- QFile *file=new QFile("temp.txt");
- if(file-> open(QIODevice::ReadWrite))
- {
- char *buffer=new char[100];
- int length;
- while((length=file-> read(buffer,100))> 0)
- {
- socket-> write(buffer,length);
- }
- }
- socket-> flush();
- file-> close();
- system("del temp.txt"); //删除临时文件
- }
- }
客户端:
只有一个Acitvity
MainActivity.Java
[java] view plain copy
- package com.tobacco.phonetest;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.util.Log;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class MainActivity extends Activity implements OnClickListener,Runnable{
- private Button button;
- private Button clear;
- private EditText editText;
- private TextView tv;
- private Socket socket;
- private PrintWriter pw;
- private BufferedReader br;
- //private InputStream is;
- private Handler handler;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- handler=new Handler();
- button=(Button)findViewById(R.id.button);
- clear=(Button)findViewById(R.id.clear);
- button.setOnClickListener(this);
- clear.setOnClickListener(this);
- editText=(EditText)findViewById(R.id.edittext);
- tv=(TextView)findViewById(R.id.textView);
- try {
- //socket=new Socket("tobacco5648.xicp.net",5648); //我的pc域名
- socket=new Socket("192.168.137.1",5648); //建立socket,这里应该根据pc的ip地址进行修改
- //socket=new Socket("www.baidu.com",80);
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Log.e("socket","unknown host");
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Log.e("socket","io execption");
- }
- if(socket==null){
- Log.e("socket","null");
- }
- else
- try {
- pw=new PrintWriter(socket.getOutputStream());
- br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"gbk"));
- String remote=socket.getInetAddress().getHostAddress();
- String self=socket.getLocalAddress().getHostAddress();
- tv.setText("connected!"+"\r\n"+"remote:"+remote+"\r\n"+"local:"+self+"\r\n");
- //is=socket.getInputStream();
- if(pw!=null& & br!=null){
- new Thread(this).start();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
- }
- public void onClick(View view) {
- if(view==button){
- String str;
- str=editText.getText().toString();
- pw.print(str);
- pw.flush();
- }
- else if(clear==view){
- tv.setText("");
- }
- }
- public void run() {
- while(true){
- try {
- String str;
- while((str=br.readLine())!=null){
- final String s=str;
- handler.post(new Runnable(){
- public void run() {
- tv.setText(tv.getText()+s+"\r\n");
- }});
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
【Android实现远程控制PC(Android[客户端]+Qt[服务器端])】http://blog.csdn.net/tobacco5648/article/details/7780385
推荐阅读
- android中的回调简单认识
- Android 外置SDCard读写权限总结
- Glow Android 优化实践
- Android中使用Notification实现宽通知栏(Notification示例二)
- Android之HttpURLConnection
- AndroidPageObjectTest_Simple.java
- Android之RecyclerView入门
- android环境下的即时通讯
- Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系