网络编程与并发编程 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())

 

posted @ 2020-09-15 12:10  Only-W  阅读(242)  评论(0编辑  收藏  举报