Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

1. 操作系统的缓冲区

  • 缓存区

    1.为什么存在缓冲区?
      暂时存储一些数据.
      缓冲区存在如果网络波动,保证数据的收发稳定,匀速.
    2.缺点: 造成了粘包现象之一.
    

2. 基于TCP协议的socket循环通信

  • 服务端(server)

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1',8848))
    server.listen()
    # listen: 允许5个人链接我,剩下的链接也可以链接,等待.
    
    conn,addr = server.accept()  # 等待客户端连接,阻塞状态中
    print(f'链接来了: {conn,addr}')
    
    while 1:
        try:
            # 等待接收客户端消息
            from_client_data = conn.recv(1024)  # 最多接受1024字节
    		# 客户端输入Q表示客户端正常退出
            if from_client_data.upper() == b'Q':
                print('客户端正常退出聊天了')
                break
    		# 打印客户端的IP以及发送过来的消息
            print(f'来自客户端{addr}消息:{from_client_data.decode("utf-8")}')
            # 给客户端返回消息
            to_client_data = input('>>>').strip().encode('utf-8')
            conn.send(to_client_data)
        except ConnectionResetError:
            print('客户端链接中断了')
            break
    conn.close()
    server.close()
    
  • 客户端(client)

    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',8848))
    
    while 1:
        to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8')
        
        # 服务端如果接受到了空的内容,服务端就会一直阻塞中,所以无论哪一端发送内容时,都不能为空发送
        if not to_server_data:
            print('发送内容不能为空')
            continue
        client.send(to_server_data)
        
        # 输入Q表示客户端正常退出
        if to_server_data.upper() == b'Q':
            break
            
         # 接收服务端返回的消息
        from_server_data = client.recv(1024)  # 最多接受1024字节
        print(f'来自服务端消息:{from_server_data.decode("utf-8")}')
    
    client.close()
    

3. 基于TCP协议的socket链接+循环 通信

  • 服务端(server)

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1',8848))	# 必须是元组
    server.listen(2)
    
    while 1:
        conn,addr = server.accept()  # 等待客户端连接,阻塞状态中
        print(f'链接来了: {conn,addr}')
    
        while 1:
            try:
                from_client_data = conn.recv(1024)  # 最多接受1024字节
    
                if from_client_data.upper() == b'Q':
                    print('客户端正常退出聊天了')
                    break
    
                print(f'来自客户端{addr}消息:{from_client_data.decode("utf-8")}')
                to_client_data = input('>>>').strip().encode('utf-8')
                conn.send(to_client_data)
            except ConnectionResetError:
                print('客户端链接中断了')
                break
        conn.close()
    server.close()
    
    
  • 客户端(client)

    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',8848))
    
    while 1:
        to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8')
        
        if not to_server_data:
            print('发送内容不能为空')
            continue
        client.send(to_server_data)
        if to_server_data.upper() == b'Q':
            break
        from_server_data = client.recv(1024)  # 最多接受1024字节
        print(f'来自服务端消息:{from_server_data.decode("utf-8")}')
    
    client.close()
    

4. 基于TCP协议的socket应用实例:执行远程命令

  • 服务端(server)

    import socket
    import subprocess
    
    server = socket.socket()
    server.bind(('127.0.0.1',8848))
    server.listen(2)
    
    while 1:
        conn,addr = server.accept()  # 等待客户端链接我,阻塞状态中
        print(f'链接来了: {conn,addr}')
    
        while 1:
            try:
                from_client_data = conn.recv(1024)  # 最多接受1024字节
    
                if from_client_data.upper() == b'Q':
                    print('客户端正常退出聊天了')
                    break
    			
                # 执行远程命令
                obj = subprocess.Popen(from_client_data.decode('utf-8'),
                                       shell=True,
                                       # 执行正确指令的管道
                                       stdout=subprocess.PIPE,
                                       # 执行错误指令的管道
                                       stderr=subprocess.PIPE,
    
                                       )
                # 将正确指令以及错误指令得到的结果返回给客户端
                result = obj.stdout.read() + obj.stderr.read()
                conn.send(result)
            except ConnectionResetError:
                print('客户端链接中断了')
                break
        conn.close()
    server.close()
    
    # shell: 命令解释器,相当于调用cmd 执行指定的命令。
    # stdout:正确结果丢到管道中。
    # stderr:错了丢到另一个管道中。
    # windows操作系统的默认编码是gbk编码。
    
  • 客户端(client)

    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',8848))
    
    while 1:
        to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8')
        
        if not to_server_data:
            print('发送内容不能为空')
            continue
        client.send(to_server_data)
        if to_server_data.upper() == b'Q':
            break
        from_server_data = client.recv(1024)  # 最多接受1024字节
        print(f'{from_server_data.decode("gbk")}')
    
    client.close()
    

5. socketserver通信

  • server服务端

    import socketserver
    
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):
            while 1:
                from_client_msg = self.request.recv(1024).decode('utf-8')
                print(f'来自客户端{self.client_address}的消息:',from_client_msg)
                to_client_msg = input('>>>')
                self.request.send(to_client_msg.encode('utf-8'))
                
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),Myserver)
        server.serve_forever()
    
  • client客户端

    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8888))
    while 1:
        to_server_msg = input('>>>').encode('utf-8')
        client.send(to_server_msg)
        from_server_msg = client.recv(1024)
        print('来自服务端的消息:',from_server_msg.decode('utf-8'))
    client.close()
    
posted @ 2019-08-16 22:11  LBZHK  阅读(366)  评论(0编辑  收藏  举报