美文网首页
编写图形界面远程控制程序

编写图形界面远程控制程序

作者: LuCh1Monster | 来源:发表于2016-03-22 00:00 被阅读316次

    课程概要:

    1. 远程控制程序的需求分析
    2. Socket通信
    3. 受控端功能强化
    4. 远程控制程序的实现与测试

    1、远程控制程序的需求分析

    一、需求

    图形化的桌面控制端程序
      控制端下达各种命令
      即时的通信与内网穿透
      受控端隐形
      控制端查看受控端桌面(下一课)

    二、架构

    受控端<---->服务器<---->控制端
      ^                  ^
      |_____________________|
    

    2、Socket通信

    • Socket介绍
    • Socket实现

    一、Socket介绍
    网络套接字(socket):在不同计算机之间通信的一个抽象,工作于TCP/IP协议中应用层和传输层

    二、Socket实现

    • 导入socket库
    • 创建socket
    • 绑定地址端口
    • 监听链接
    • 发送接收数据

    【Master.py】

    #-*-coding:utf8-*-
    
    import wx
    from MasterSocket import MasterSocket
    import threading
    
    # SERVER = '128.199.151.202'
    SERVER = '192.168.2.100'
    PORT = 5000
    
    '''基于Sizer的控件相对布局'''
    class Slave(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, parent=None, id=-1, title=u'极客学院', size=(600, 600))
            self.panel = wx.Panel(self, -1)
            self.lock = threading.Lock()
            self.Centre()
    
            #定义我们需要的各个控件
    
            commandStatic = wx.StaticText(self.panel, -1, u'输命令:')
            writePyStatic = wx.StaticText(self.panel, -1, u'写代码:')
    
            self.commandText = wx.TextCtrl(self.panel, -1, u'')
            self.writePyText = wx.TextCtrl(self.panel, -1, u'''#-*-coding:utf-8-*-\n#python code here''',
                                      style=wx.TE_MULTILINE, size=(300, 200))
    
            self.send = wx.Button(self.panel, label=u'发送命令')
            self.clear = wx.Button(self.panel, label=u'清空命令')
            self.screen = wx.Button(self.panel, label=u'查看屏幕')
            self.refresh = wx.Button(self.panel, label=u'刷新')
    
            # self.serverList = ['192.168.0.4', '10.19.2.1', '192.168.0.111', '172.26.123.5', '192.168.6.11', '192.99.8.8']
            self.serverList = []
            self.server = wx.ListBox(self.panel, -1, size=(120, 100), choices=self.serverList, style=wx.LB_SINGLE)
    
            img = wx.Image(r'logo.jpg', wx.BITMAP_TYPE_ANY).Scale(200, 200)
            self.screenBox = wx.StaticBitmap(self.panel, -1, wx.BitmapFromImage(img))
    
            self.Bind(wx.EVT_BUTTON, self.onSend, self.send)
            self.Bind(wx.EVT_BUTTON, self.onClear, self.clear)
            self.Bind(wx.EVT_BUTTON, self.onScreen, self.screen)
            self.Bind(wx.EVT_BUTTON, self.onRefresh, self.refresh)
    
            #基于GirdBagSizer布局
            self.gridBagSizerAll = wx.GridBagSizer(hgap=5, vgap=5)
            self.gridBagSizerAll.Add(self.server, pos=(0, 0),
                                flag=wx.ALL | wx.EXPAND,
                                span=(6, 2), border=5)
            self.gridBagSizerAll.Add(self.refresh, pos=(6, 0),
                                flag=wx.ALL | wx.EXPAND,
                                span=(1, 2), border=5)
    
            self.gridBagSizerAll.Add(commandStatic, pos=(0, 2),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                border=5)
            self.gridBagSizerAll.Add(self.commandText, pos=(0, 3),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(1, 2), border=5)
    
            self.gridBagSizerAll.Add(writePyStatic, pos=(1, 2),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(1, 3), border=5)
            self.gridBagSizerAll.Add(self.writePyText, pos=(2, 2),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(4, 3), border=5)
            self.gridBagSizerAll.Add(self.send, pos=(6, 2),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(1, 1), border=5)
            self.gridBagSizerAll.Add(self.clear, pos=(6, 3),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(1, 1), border=5)
            self.gridBagSizerAll.Add(self.screen, pos=(6, 4),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(1, 1), border=5)
    
            self.gridBagSizerAll.Add(self.screenBox, pos=(0, 5),
                                flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                                span=(7, 2), border=5)
    
            self.panel.SetSizer(self.gridBagSizerAll)
    
            # self.SetSizeHints(250, 200, 700, 400) #设定窗口的最大最小值
            self.gridBagSizerAll.AddGrowableCol(0, 1)
            self.gridBagSizerAll.AddGrowableCol(1, 1)
            self.gridBagSizerAll.AddGrowableCol(2, 1)
            self.gridBagSizerAll.AddGrowableCol(3, 1)
            self.gridBagSizerAll.AddGrowableCol(4, 1)
            self.gridBagSizerAll.AddGrowableCol(5, 1)
            self.gridBagSizerAll.AddGrowableCol(6, 1)
    
            self.gridBagSizerAll.AddGrowableRow(0, 1)
            self.gridBagSizerAll.AddGrowableRow(1, 1)
            self.gridBagSizerAll.AddGrowableRow(2, 1)
            self.gridBagSizerAll.AddGrowableRow(3, 1)
            self.gridBagSizerAll.AddGrowableRow(4, 1)
            self.gridBagSizerAll.AddGrowableRow(5, 1)
            self.gridBagSizerAll.AddGrowableRow(6, 1)
            self.gridBagSizerAll.Fit(self)
    
        def onSend(self, event):
            server = self.server.GetSelection()
            if server != -1:
                slave = self.serverList[server]
                command = self.commandText.GetValue()
                writePy = self.writePyText.GetValue()
                if command:
                    print u'输入的命令是: %s' % command
                    self.masterSocket = MasterSocket(SERVER, PORT, command, commandType='commandInConfig', to=slave)
                elif writePy:
                    self.masterSocket = MasterSocket(SERVER, PORT, writePy, commandType='commandInWrite', to=slave)
                else:
                    print u'请输入命令'
                    return None
                self.masterSocket.setDaemon(True)
                self.masterSocket.start()
            else:
                print u'请先选择被控端。'
                return None
    
        def onClear(self, event):
            self.commandText.Clear()
            self.writePyText.Clear()
            self.writePyText.AppendText(u'''#-*-coding:utf-8-*-\n#Python code here''')
    
        def onScreen(self, event):
            img = wx.Image(r'python.jpg', wx.BITMAP_TYPE_ANY).Scale(300, 200)
            self.screenBox.SetBitmap(wx.BitmapFromImage(img))
            self.gridBagSizerAll.Fit(self)
    
        def onRefresh(self, event):
            self.serverList = []
    
            socketForServerList = MasterSocket(SERVER, PORT, 'listSlave', self.serverList)
            socketForServerList.setDaemon(True)
            socketForServerList.start()
            socketForServerList.join()
    
            self.lock.acquire()
            print u'被控端列表111:%s' % str(self.serverList)
            self.server.Clear()
            for each in self.serverList:
                self.server.Append(each)
            self.lock.release()
    
    if __name__ == "__main__":
        app = wx.App()
        frame = Slave()
        frame.Show()
        app.MainLoop()
    
    

    【MasterSocket.py】

    #-*-coding:utf8-*-
    import socket
    import threading
    import time
    import json
    
    class MasterSocket(threading.Thread):
        BUFFER_SIZE = 2048*100
    
        def __init__(self, host='', port=5000, command='', serverList=None, commandType='', to='', timeout=5):
            threading.Thread.__init__(self)
            self.connected = False
            self.sock = None
            self.host = host
            self.port = port
            self.command = command
            self.timeout = timeout
            if serverList is not None:
                self.serverList = serverList
    
            if to:
                self.to = to
            else:
                self.to = ''
            if commandType:
                self.commandType = commandType
            else:
                self.commandType = ''
    
        def connect(self):
            startTime = time.time()
            timeDelta = 0
            while timeDelta <= self.timeout:
                try:
                # 创建客户端套接字
                    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    # 连接到服务器
                    self.sock.connect((self.host, self.port))
                    self.connected = True
                    return True
                except Exception, _:
                    time.sleep(1)
                    timeDelta = int(time.time() - startTime)
            if timeDelta > self.timeout:
                print u'连接超时'
                return False
    
        def run(self):
            print u'开始连接...'
            if self.connect():
                print u'连接成功'
                try:
                    self.send(self.command)
                except Exception, e:
                    print 'socket error, because: %s ' % str(e)
    
        def generateJson(self, fromWhere, command, to='', commandType=''):
            commandDict = {'from': fromWhere, 'to': to, 'command': command, 'type': commandType}
            return json.dumps(commandDict)
    
        def send(self, command):
            print u'往服务器发送数据: %s' % command
            receiveData = ''
            try:
                # 发起数据给服务器
                self.sock.sendall(self.generateJson('master', command, to=self.to, commandType=self.commandType))
    
                while '#finished#' not in receiveData:
                    # 接收服务器返回的数据
                    data = self.sock.recv(self.BUFFER_SIZE)
                    receiveData += data
                print u'收到服务器返回: %s' % receiveData
                self.analysisResult(receiveData)
    
            except socket.errno, e:
                print 'Socket error: %s' % str(e)
            except Exception, e:
                print 'Other exception: %s' % e
            finally:
                print u'关闭socket'
                self.sock.close()
    
        def analysisResult(self, result):
            print u'开始分析返回信息: %s' % result
            if result:
                try:
                    resultDict = json.loads(result[:-10])
                except Exception, e:
                    print u'返回信息有误'
                    return ''
                if 'slaveList' in resultDict:
                    self.serverList += resultDict['slaveList']
                    print u'被控端列表: %s' % str(self.serverList)
                    # self.sock.close()
    

    【simpleServer.py】

    #-*-coding:utf8-*-
    import socket
    
    class SimpleServer:
        BUFFER_SIZE = 2048*100
    
        def __init__(self, host='', port=5000):
            self.sock = None
            self.host = host
            self.port = port
    
        def connect(self):
            try:
                self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.sock.bind((self.host, self.port))
                # 开启socket监听
                self.sock.listen(5)
            except Exception, e:
                print 'socket 错误: %s' % str(e)
                return None
    
        def receive(self):
            if self.sock:
                conn, addr = self.sock.accept()
                print '收到来自 %s的连接' % str(addr)
                while True:
                    # 读取数据,数据还没到来阻塞
                    data = conn.recv(self.BUFFER_SIZE)
                    if len(data):
                        print u'收到来自: %s, 的信息: %s' % (addr[0], data)
                        conn.sendall(u'I have received the data: %s' % data)
                    else:
                        print u'socket 连接中断。'
                        break
    
    if __name__ == '__main__':
        HOST = ''      # 服务器主机地址
        PORT = 5000         # 服务器监听端口
    
        simple = SimpleServer(HOST, PORT)
        simple.connect()
        while True:
            print u'等待连接建立...'
            simple.receive() #进程运行到这里就会阻塞,直到第一次连接主动或者意外断开,才会进入第二次循环。认识到这一点非常重要。
    

    相关文章

      网友评论

          本文标题:编写图形界面远程控制程序

          本文链接:https://www.haomeiwen.com/subject/ronklttx.html