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()
      
  • 相关阅读:
    Oracle函数如何把符串装换为小写的格式
    Oralce中的synonym同义词
    JS中getYear()的兼容问题
    How to do SSH Tunneling (Port Forwarding)
    所谓深度链接(Deep linking)
    upload size of asp.net
    发一个自动刷网站PV流量的小工具
    解决Visual Studio 2008 下,打开.dbml(LINQ) 文件时,提示"The operation could not be completed." 的问题。
    在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录
    使用SQL语句获取Sql Server数据库的版本
  • 原文地址:https://www.cnblogs.com/liubing8/p/11366636.html
Copyright © 2011-2022 走看看