zoukankan      html  css  js  c++  java
  • 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()
      
  • 相关阅读:
    【LCT维护基环内向树森林】BZOJ4764 弹飞大爷
    【LCT】BZOJ3091 城市旅行
    【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
    【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅
    【LCT】BZOJ2049 [SDOI2008]Cave 洞穴勘测
    【有上下界的网络流】ZOJ2341 Reactor Cooling(有上下界可行流)
    【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)
    从输入url到页面加载的过程
    forEach和map的区别
    理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。
  • 原文地址:https://www.cnblogs.com/liubing8/p/11366636.html
Copyright © 2011-2022 走看看