zoukankan      html  css  js  c++  java
  • 网络编程与并发编程 11

     

    一、远程执行命令

    struct模块的应用

    import struct

    res=struct.pack('i',1333123129)
    print(res,len(res))

    recv_header=struct.unpack('i',res)
    print(recv_header[0])

    服务端

    import socket
    import subprocess
    import struct

    server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 流式协议=》tcp
    # print(server)
    server.bind(('127.0.0.1',8080))
    server.listen(5)

    # 链接循环
    while True:
       conn,addr=server.accept()
       print(addr)

       # 通信循环
       while True:
           try:
               cmd=conn.recv(1024)
               if len(cmd) == 0:break  # 针对linux
               obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE
                                    )

               stdout_res=obj.stdout.read()
               stderr_res=obj.stderr.read()
               total_size=len(stdout_res) + len(stderr_res)
               print(total_size)

               # 1、先发送数据的总大小
               conn.send(struct.pack('i',total_size))

               # 2、再发送真实的数据
               conn.send(stdout_res)
               conn.send(stderr_res)
           except Exception:  # 针对windows
               break
       conn.close()
    server.close()

    客户端

    import socket
    import struct

    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 流式协议=》tcp
    client.connect(('127.0.0.1',8080))

    while True:
       cmd=input(">>>: ").strip()
       if len(cmd) == 0:continue
       client.send(cmd.encode('utf-8'))
       # 1、先拿到数据的总大小
       header_bytes=client.recv(4)
       header=struct.unpack('i',header_bytes)
       total_size=header[0]

       # 2、再接收数据
       recv_size=0
       res=b''
       while recv_size < total_size:
           data=client.recv(1024)
           recv_size+=len(data)
           res+=data

       print(res.decode('gbk'))

     

    二、解决粘包问题

    struct模块的应用

    import struct
    import json

    header_dic={
       'filenme':"a.txt",
       'md5':"sdfasfdasfdasfd123123213",
       "total_size":999999912343123442802
    }

    header_json=json.dumps(header_dic)

    header_json_bytes=header_json.encode('utf-8')

    # print(header_json_bytes)
    # print(len(header_json_bytes))

    服务端

    import socket
    import subprocess
    import struct
    import json

    server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 流式协议=》tcp
    # print(server)
    server.bind(('127.0.0.1',8080))
    server.listen(5)

    # 链接循环
    while True:
       conn,addr=server.accept()
       print(addr)

       # 通信循环
       while True:
           try:
               cmd=conn.recv(1024)
               if len(cmd) == 0:break  # 针对linux
               obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE
                                    )

               stdout_res=obj.stdout.read()
               stderr_res=obj.stderr.read()
               total_size=len(stdout_res) + len(stderr_res)
               print(total_size)

               header_dic = {
                   'filenme': "a.txt",
                   'md5': "sdfasfdasfdasfd123123213",
                   "total_size": total_size
              }
               header_json = json.dumps(header_dic)
               header_json_bytes = header_json.encode('utf-8')

               # 1、先发送报头的长度
               conn.send(struct.pack('i',len(header_json_bytes)))

               # 2、再发送报头
               conn.send(header_json_bytes)

               # 3、然后发送真实的数据
               conn.send(stdout_res)
               conn.send(stderr_res)
           except Exception:  # 针对windows
               break
       conn.close()
    server.close()

    客户端

    import socket
    import struct
    import json

    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 流式协议=》tcp
    client.connect(('127.0.0.1',8080))

    while True:
       cmd=input(">>>: ").strip()
       if len(cmd) == 0:continue
       client.send(cmd.encode('utf-8'))

       # 1、先拿到报头的长度
       header_json_bytes_size=struct.unpack('i',client.recv(4))[0]
       # 2、再收报头
       header_json_bytes=client.recv(header_json_bytes_size)
       header_json=header_json_bytes.decode('utf-8')
       header_dic=json.loads(header_json)
       print(header_dic)

       # 3、最后接收数据
       total_size=header_dic['total_size']
       recv_size=0
       res=b''
       while recv_size < total_size:
           data=client.recv(1024)
           recv_size+=len(data)
           res+=data

       print(res.decode('gbk'))

     

    三、基于udp协议的套接字通信

    服务端

    # import socket
    from socket import *
    import time

    server=socket(AF_INET,SOCK_DGRAM)
    server.bind(('127.0.0.1',8080))

    while True:
       data,client_addr=server.recvfrom(1024)
       time.sleep(10)
       server.sendto(data.upper(),client_addr)

    客户端

    # import socket
    from socket import *

    client = socket(AF_INET, SOCK_DGRAM)

    while True:
       msg=input('>>>: ').strip()
       client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
       data,server_addr=client.recvfrom(1024)
       print(data.decode('utf-8'))

     

    四、socketserver模块

    TCP协议

    服务端

    import socketserver

    class MyrequestHandler(socketserver.BaseRequestHandler):
       def handle(self):
           # self.request # conn对象
           print(self.client_address)
           while True:
               try:
                   data=self.request.recv(1024)
                   if len(data) == 0:break
                   self.request.send(data.upper())
               except Exception:
                   break
           self.request.close()

    if __name__ == '__main__':
       s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyrequestHandler)
       s.serve_forever()

    客户端

    import socket
    import struct

    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 流式协议=》tcp
    client.connect(('127.0.0.1',8080))

    while True:
       cmd=input(">>>: ").strip()
       if len(cmd) == 0:continue
       client.send(cmd.encode('utf-8'))
       data=client.recv(1024)
       print(data.decode('utf-8'))

    udp协议

    服务端

    import socketserver
    import time

    class MyrequestHandler(socketserver.BaseRequestHandler):
       def handle(self):
           # self.request # conn对象
           data=self.request[0]
           self.request[1].sendto(data.upper(),self.client_address)
           time.sleep(10)

    if __name__ == '__main__':
       s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyrequestHandler)
       s.serve_forever()

    客户端

    # import socket
    from socket import *

    client = socket(AF_INET, SOCK_DGRAM)

    while True:
       msg=input('>>>: ').strip()
       client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
       data,server_addr=client.recvfrom(1024)
       print(data.decode('utf-8'))

    五、异常处理

    1、什么是异常

    异常是错误发生的信号,程序中一旦出现错误,python就会产生一个异常 一旦该异常没有被处理,该异常就会抛出来,程序的运行也随即终止

    2、为何要处理异常

    为了增强程序的容错性、鲁棒性、健壮性

    3、异常的三个组成部分

    异常的追踪信息 异常的类型 异常的内容

    4、错误=》异常

    4.1 语法错误:SyntaxError

    应该在程序运行前就改正

    4.2 逻辑错误

    age=input(">>: ").strip()
    if age.isdigit():
       age=int(age)
       print(age > 10)

    5、异常处理的语法

    try:
       代码1
       代码2
       代码3
    except 异常类型1 as e:
       处理异常的代码1
    except 异常类型2 as e:
       处理异常的代码2
    except (异常类型3,异常类型4,异常类型5) as e:
       处理异常的代码3
    except Exception as e:
       处理异常的代码4
    else:
       被监测的代码块没有发生异常时执行的代码
    finally:
       无论被监测的代码块有无异常都会执行该代码

    print('===>other code<====')

    try不能单独和else连用,如果要用else,必须配合except

    try:
       print(111)
       print(222)
       print(3333)
    except Exception:
       pass
    else:
       print('ok')
    print('===>other code<====')
    try:
       print('start...')
       l=[]
       l[100]
       print('end...')
    except KeyError as e:
       print("Key错误:",e)
    except IndexError as e:
       print("索引错误:",e)
    except Exception:
       pass
    print('===>other code<====')
    try:
       执行sql1
       执行sql2
       执行sql3
       执行sql4
       执行sql5
    except Exception:
       执行回滚操作
    else:
       执行提交操作
    print('===>other code<====')
    try:
       print(1111)
       sadf
       print(2222)
       print(33333)
    finally:
       print('====>finally')
       # 回收资源

    =======================断言===================

    # 上半部分
    print(111)
    print(222)
    print(333)
    names=['egon','jack',]

    # if len(names) != 3:
    #     raise Exception("数据错误")
    assert len(names) == 3

    # 下半部分
    print(names[2])

    =======================raise主动抛出异常===================

    class NameType(BaseException):
       def __init__(self,msg):
           self.msg=msg
       def __str__(self):
           return "<%s>" %self.msg

    class People:
       def __init__(self,name):
           self.__name=name

       @property
       def name(self):
           return self.__name

       @name.setter
       def name(self,v):
           if not isinstance(v,str):
               raise NameType("名字必须是str类型")
           self.__name=v

       @name.deleter
       def name(self):
           del self.__name

    obj=People('egon')
    obj.name=123123
    class Animal:
       def speak(self):
           raise Exception("必须定义speak方法")

       def run(self):
           raise Exception("必须定义run方法")


    class Dog(Animal):
       pass

    class People(Animal):
       pass


    obj1=Dog()
    obj2=People()


    obj1.speak()
    # obj1.run()

     

    六、操作系统发展史

    多道技术

    空间上的复用:将内存分为几部分,每个部分放入一个程序,这样,同一时间内存中就有了多道程序。 时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,则cpu的利用率可以接近100%,类似于我们小学数学所学的统筹方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到io时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)

    程序

    一堆代码文件

    进程

    一个正在运行的程序or程序的运行过程

    并发:

    多个进程/任务看起来是同时运行的

    并行:

    多个进程/任务是真正意义上的同时运行

    进程的三种运行状态

    运行态

    就绪态

    阻塞态

    任务的提交方式

    同步

    异步

    计算机体系结构

    七、开启子进程

    方式一:

    from multiprocessing import Process
    import time


    def task(n):
       print('starting...',x)
       time.sleep(n)
       print('end...')

    x = 100

    if __name__ == '__main__':
       p=Process(target=task,args=(3,))
       p.start()  # 发生系统调用,让操作系统启动进程
       print('主。。。。',x)

    方式二

    from multiprocessing import Process
    import time

    x = 100

    class Myprocess(Process):
       def __init__(self,n):
           self.n = n
           super().__init__()

       def run(self) -> None:
           print('starting...', x)
           time.sleep(self.n)
           print('end...')

    if __name__ == '__main__':
       p=Myprocess(3)
       p.start()
       print("主。。。")

     

    八、进程空间彼此隔离

    from multiprocessing import Process
    import time


    x = 100

    def task(n):
       global x
       print('starting...')
       time.sleep(n)
       x=0
       print('end...')


    if __name__ == '__main__':
       p=Process(target=task,args=(3,))
       p.start()  # 发生系统调用,让操作系统启动进程
       time.sleep(10)
       print('主。。。。',x)

     

    九、join方法

    from multiprocessing import Process
    import time
    import os

    def task(n):
       print(os.getpid(),os.getppid())
       print('进程 %s starting...' %n)
       time.sleep(n)
       print('进程 %s end...' %n)



    if __name__ == '__main__':
       p1=Process(target=task,args=(1,))
       p2=Process(target=task,args=(2,))
       p3=Process(target=task,args=(3,))
       p1.start()  # 发生系统调用,让操作系统启动进程
       p2.start()  # 发生系统调用,让操作系统启动进程
       p3.start()  # 发生系统调用,让操作系统启动进程


       start=time.time()
      # time.sleep(10)
       p3.join()
       p1.join()
       p2.join()
       print(time.time() - start)

       p3.terminate()
       print(p3.is_alive())
       print(p3.name)
       print(p3.pid)
       p3.join(1)

       print('主。。。。',os.getpid())

     

  • 相关阅读:
    @atcoder
    @loj
    @AGC037
    @uoj
    @uoj
    @loj
    @loj
    @loj
    @loj
    @loj
  • 原文地址:https://www.cnblogs.com/2722127842qq-123/p/13672378.html
Copyright © 2011-2022 走看看