• socketserve及其应用


    1.cmd命令 利用socket

    socket服务端

     1 import socket
     2 import subprocess
     3 s = socket.socket()
     4 s.bind(("127.0.0.1",8000))
     5 s.listen(3)
     6 print("waiting...")
     7 while 1:
     8     conn,addr = s.accept()
     9     print(conn)
    10     while 1:
    11         try:
    12             a = conn.recv(1024)
    13         except Exception:
    14             break
    15         if not a:
    16             break
    17         print(">>>",str(a,"utf8"))
    18         obj  = subprocess.Popen(a.decode("utf8"),shell=True,stdout=subprocess.PIPE)
    19         result = obj.stdout.read()
    20         print('ooooo',type(result))
    21         result_len = bytes(str(len(result)),"utf8") # result是unicode编码下的十六进制 所以先转换成字符串(Unicode) 在转换成bytes
    22         conn.sendall(result_len)  # 两个send在一起容易发生粘包 特别是第一个数据特别小的时候
    23         conn.sendall(result)      # 所以在send之间在来个一收一发
    24 s.close()

    client客户端

     1 import socket
     2 s = socket.socket()
     3 ss = ("127.0.0.1",8000)
     4 s.connect(ss)
     5 while 1:
     6     inp = input(">>>")
     7     if inp =="q":
     8         break
     9     s.send(bytes(inp,"utf8"))    # send 传送智能是bytes类型
    10     result_len = int(str(s.recv(1024),"utf8"))    # 二进制的不能直接转换成整形!!!
    11     print(result_len)
    12     data = bytes()
    13     while len(data)!=result_len:    # 大文件传输过程中  不能一次传完 造成延迟 所以要先
    14         data += s.recv(1024)    # 传输文件的大小 根据大小判断文件传输
    15     print(str(data,"gbk"))
    16 s.close()

    上述的代码实现了client端发送cmd指令到serve端进行执行后返回给client端结果的一个过程。

    attention:一发一收

    socket创建

      s = socket.socket()这样就创建了一个socket对象。在serve端和client端分别需要创建一个。括号中仍有4个默认函数:

      family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None

      其中family是IPV4 的默认值,type是TCP的默认值。

    设置值

      创建好socket之后,serve端需要设置(4,5行)

      1 bind绑定IP和端口。

      2 listening值是最多等待。

      3 接受client协议和地址 即 第八行

      4 注意这里的conn就是client端的.socket 所以在接收的时候为conn.receive

      client端只用设置连接的address和端口。

    小细节

      1.serve端的try是防止client端直接结束造成接收报错。

      2.若接收的a为空表示client端主动断开了socket连接(本身发送不能发送空)。

    关于subprocess

      obj = subprocess.Popen(a.decode("utf8"),shell=True,stdout=subprocess.PIPE)
      result = obj.stdout.read()

      这两句话实现了cmd在子程序中运行后返回结果到result。

      注意这里的result是gbk编码下的bytes类型。

    关于这其中杂乱的编码

      Python3中有两种格式:

        str:str>>bytes 称为编码(encode)方法有1.re=bytes(“ccc”,“utf8”)2.re=“ccc”.encode(“utf8”)py3中str都是Unicode编码。兼容utf8,三字节表示中文。

        bytes:bytes>>str称为解码(decode)方法有1.re = str(“ccc”,“utf8”)2.re=“ccc”.decode(“utf8”)bytes类型有相对应的编码协议。即什么样的编码形式               (如utf8)就仍用什么样的解码。

      Python2中也有两种:

        str:即原来的3中的bytes

        Unicode:即str u“你好” 表示内容用的Unicode编码。

      pyhton3中页面用到utf8,2中用的阿斯克码。

    大文件传输问题解决

      发送端的sendall必将数据都发送过去,但是接收的时候一次最多接收设置值1024个字节。(received值最大8K)所以造成接收时显示缓慢。(接收第二条时仍旧显示第      一条)

      解决办法是:多次循环接收直到data大小等于文件大小。while len(data)!=result_len:不相等就继续接收。

     2.socketserve

    serve端

     1 import socketserver
     2 class Myserve(socketserver.BaseRequestHandler):
     3     def handle(self):
     4         print("active")
     5         while 1:
     6             conn = self.request
     7             print(self.client_address)
     8             while 1:
     9                 a = conn.recv(1024)
    10                 print(">>>", str(a, "utf8"))
    11                 if not a:
    12                     break
    13                 inp = input(">>>")
    14                 conn.send(bytes(inp, "utf8"))
    15             conn.close()
    16 mine = socketserver.ThreadingTCPServer(("127.0.0.1",8000),Myserve)
    17 mine.serve_forever()

    上述通过调用socketserver实现了多个client和一个server进行通信的功能。

    实现过程:

      创建一个自己命名的server类myserver

      只在此类中创建一个方法:handle名字不能变,逻辑按照功能设计

      创建socketserver对象,调用ThreadingTCPServer方法传入address元组,和server。

      serverforever()激活这个并发的server。

      

  • 相关阅读:
    使用四元数点乘比较插值是否即将完成
    ShadowGun Demo学习(非技术向)
    测试-关于Unity获取子层级内容的几种接口(Transform FindChild, Component GetComponentInChildren,...)
    Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制
    Javascript事件模型系列(一)事件及事件的三种模型
    在代码中设置IE9的默认文档模式
    如何在博客园的文章/随笔中添加可运行的js代码
    jquery插件:仿百度首页可展开收起的消息提示控件
    有“镜头感”的网页是如何实现的
    HTML5 history API实践
  • 原文地址:https://www.cnblogs.com/khal-Cgg/p/5919236.html
Copyright © 2020-2023  润新知