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()
      
  • 相关阅读:
    js == 和 === 判断原理
    react 渲染原理
    常见的HTTP状态码
    类数组和数组的区别是什么?
    如何判断一个变量是不是数组?
    typeof 是否正确判断类型? instanceof呢? instanceof 的实现原理是什么?
    前端 js data数组转tree数据结构
    Echarts 基础学习
    Vue CLI 4.0 项目搭建
    Echarts Demo
  • 原文地址:https://www.cnblogs.com/liubing8/p/11366636.html
Copyright © 2011-2022 走看看