Python网络编程(基础总结 入门经典)

  1. 云栖社区>
  2. 博客>
  3. 正文

Python网络编程(基础总结 入门经典)

巴黎香榭 2018-08-18 23:40:28 浏览2423
展开阅读全文
Linux下文件类型:
    bcd -lsp
         b(块、设备文件)
         c(字符设备文件)
         d(目录)
         -(普通文件)
         l(链接文件)
         s(套接字文件)
         p(管道文件)
    kill -sig pid:通过pid发送信号杀死指定进程
    kill -l:查看操作系统内所所有sig信号
    ps -aux ---> STAT表示进程状态
    信号:
        SIGHUP   断开链接
    SIGINT   Ctrl + c
    SIGQUIT  Ctrl + \
    SIGTSTP  Ctrl + z
    SIGKILL  终止进程且不能被处理
    SIGSTOP  暂停进程且不能被处理
    SIGALRM  时钟信号
    SIGCHLD  子进程改变状态时父进程会收到此信号


OSI七层模型 -----> 网络通信的标准化流程

    应用层: 提供用户服务,具体的内容由特定的程序规定
    表示层: 提供数据的加密和压缩优化
    会话层: 确定建立应用链接,选择传输服务
    传输层: 提供数据传输服务,进行流量控制
    网络层: 路由选着,网络互联
    链路层: 提供链路交换,具体消息的发送
    物理层: 物理硬件,接口,网卡的规定
网络协议:
应用层:TFTP(文件传输)、HTTP(超文本传输协议)、DNS(域名解析)、SMTP(邮件传输)
传输层:TCP、UDP
网络层:IP
物理层:IEEE
IP地址
本地使用:127.0.0.1 或 “localhost”
网络地址:“0.0.0.0” 或 “172.168.40.53”
IPv4: 点分十进制   例如:192.168.1.3   取值0~255(32位)
IPv6: 128位


socket模块:
    ifconfig:查看本机IP (ens33:本地IP  lo:本地回还)
    ipconfig:windoes中
    socket.gethostname() :                        获取本机主机名
    socket.gethostbyname('tedu') :                利用主机名获取ip
    socket.gethostbyname('localhost'):    获取本地ip
    socket.gethostbyaddr('127.0.0.1')      访问主机IP地址
    socket.inet_aton('192.168.1.2')        IP十六进制转换
    socket.inet_ntoa(b'\xc0\xa8\x01\02')  IP十进制转换
    socket.getservbyname('ssh')            获取应用程序的端口
创建TCP服务端套接字:
sockfd.socket(sock_family = AF_INET,
               sock_tpye = SOCK_STREAM,
               proto = 0)
    sockfd.bind(addr)      绑定地址
    sockfd.listen(n)          设置监听套接字
  connfd,addr = sockfd.accept() 等待接受客户端链接
  data = connfd.recv(buffersize) 接收消息
  connfd.send(data) 发送消息
  sockfd.close() 关闭套接字
创建TCP客户端套接字:
sockfd.socket(sock_family = AF_INET,
               sock_tpye = SOCK_STREAM,
               proto = 0)
    sockfd.bind(addr)      绑定地址
  sockfd.connect(addr) 链接服务端
  data = connfd.recv(buffersize) 接收消息
  connfd.send(data) 发送消息
  sockfd.close() 关闭套接字


创建UDP客户端套接字:
  sockfd.socket(sock_family = AF_INET,
               sock_tpye = SOCK_DGRAM,
               proto = 0)
    sockfd.bind(addr)      绑定地址
  data = sockfd.recvfrom(buffersize) 接收消息
  sockfd.sendto(data, addr) 发送消息
  sockfd.close() 关闭套接字
创建UDP客户端套接字:
  sockfd.socket(sock_family = AF_INET,
               sock_tpye = SOCK_DGRAM,
               proto = 0)
  data = sockfd.recvfrom(buffersize) 接收消息
  sockfd.sendto(data, addr) 发送消息
  sockfd.close() 关闭套接字

创建本地套接字服务端:
  sockfd = socket(AF_UNIX, SOCK_STREAM) 创建本地套接字对象
  sockfd.bind(file) 绑定套接字文件
  sockfd.listen(3) 监听
  connfd,addr = sockfd.accept() 等待链接
  connfd.recv(buffersize) 接收消息
  connfd.send(data) 发送消息
  sockfd.close() 关闭套接字
创建本地套接字客户端:
  sockfd = socket(AF_UNIX, SOCK_STREAM) 创建本地套接字对象
  sockfd.connect(sock_file) 链接服务端
  connfd.recv(buffersize) 接收消息
  connfd.send(data) 发送消息
  sockfd.close() 关闭套接字



套接字属性:
  sockfd.type 返回套接字类型
  sockfd.family 返回地址类型
套接字方法:
  sockfd.fileno() 获取套接字的文件描述符
  sockfd.getsockname() 获取套结字绑定的地址
  sockfd.getpeername() 获取链接套接字客户端的地址
  sockfd.setsockopt(level,optname, value) 设置端口可立即重用
  sockfd.setblocking(False) 将套接字设置为非阻塞状态
  sockfd.settimeout(sec) 设置套接字的超时时间

select模块: IO多路复用,阻塞等待监控的IO事件发生
rs, ws, xs = select(rlist, 等待处理的IO
  wlist 想要主动处理的IO
  xlist[, 出错希望去处理的IO
  timeout]) 超时检测
p = select.poll 创建poll对象
p.register(s, POLLIN | PLLERR) 注册关注的IO
events = p.poll() 监控关注的IO事件

multiprocessing模块: 创建进程对象
Process(target, 要绑定的函数
name, 给进程起的名称
args, 元组给target函数位置传参
kwargs) 字典给target函数键值传参
p.start() 启动进程terget绑定函数
p.join([timeout]) 阻塞等待子进程退出
p.name                        获取进程名(属性)
p.daemon 设置为True主进程结束杀死所有子进程(必须start()前设置)
p.is_alive() 判断进程是处于alive状态(存活)
p.pid 获取创建进程的pid号(属性)

pool = pool(x) 创建进程池对象(进程池大小)
pool.apply_async(fun, 要执行的函数(异步执行)
args, 以元组形式为fun传参
kwds) 以字典形式为fun传参
pool.apply(fun, args, kwds) (同步执行)
r = pool.map(fun,range(6)) 将要执行的事件放入进程池
pool.close() 关闭进程池
pool.join() 回收进程池

fd1,fd2 = Pipe(duplex=True) 创建管道(Flase:fd1只读,fd2只写)
fd.recv() 从管道读取信息空则阻塞
fd.send(data) 向管道写入内容满则阻塞

q = Queue(maxsize=0) 创建队列对象(存放多少条消息)
q.put(data, 存入消息(支持Python数据类型)
   [block, 默认阻塞 False:非阻塞
   timeout]) block为True是表示超时检测
data = q.get([block,timeout]) 取出消息
q.full() 判断队列是否为满
q.empty()    判断队列是否为空
q.qsize()    获取队列中消息的数量
q.close()    关闭队列

shm = Value(ctype, 创建共享内存共享空间
obj) ctype字符串:(C语言数据类型),obj初始数据
shm.value 表示共享内存的值(可以赋值)
shm = Array(ctype,obj) 创建共享内存共享空间

sem = Semaphore(num) 创建信号量
sem.acquire() 将信号量减1  0时阻塞
sem.release() 将信号量加1
sem.get_value() 获取当前信号量的值(数量)

e = Event() 创建Event事件对象
e.wait([timeout]) 阻塞进程 直到事件对象被set
e.set.() 让事件对象变为被设置状态
e.clear() 使事件对象清除设置状态
e.is_set() 判断当前事件是否被set

Lock = Lock() 创建锁对象
lock.acquire() 上锁
lock.release() 解锁

threading 模块: 创建线程对象
threshold.Thread(target, 线程函数
  name, 线程名字
  args, 元组给线程函数位置传参
  kwargs) 字典给线程函数位置传参
t.start() 启动线程
t.join()  回收线程
t.name 线程名
t.daemon = True 主线程退出分支线程也退出
t.setDaemon(True) 主线程退出分支线程也退出
t.isDaemon 查看daemon值
t.setName(“name”) 设置线程名称
t.is_alive() 查看线程状态
threading.currentThread() 获取当前进程对象

e = threading.Event() 创建Event事件对象
e.wait([timeout]) 事件阻塞
e.set() 设置事件
e.clear() 清除事件

lock = threading.Lock() 创建锁对象
lock.acquire() 上锁
lock.release() 解锁


socketserver集成并发模块:
StreamRequestHandler    处理tcp请求
DatagramRequestHandler  处理udp请求

ForkingMixIn    创建多进程
ThreadingMixIn  创建多线程
 
TCPServer  创建tcp  server
UDPServer  创建udp  server

ForkingTCPServer      ForkingMixIn  +  TCPServer 
ForkingUDPServer      ForkingMixIn  +  UDPServer 
ThreadingTCPServer    ThreadingMixIn  +  TCPServer 
ThreadingUDPServer    ThreadingMixIn  +  UDPServer 



signal模块:
signal.alarm(sec) 设置时钟信号给自己SIGALRM信号
signal.pause() 阻塞进程,等待一个信号
signal.signal(sig, 要处理的信号
   handler) 处理方法(SIG_DFL:默认 SIG_IGN:忽略 func:自定义函数)


sys模块补充:
    sys.argv 获取从命令行获取的参数内容列表
    sys.stdin    0 标准输入IO文件描述符
    sys.stdout   1 标准输出IO文件描述符
    sys.stderr   2 错误IO文件描述符
    sys.exit([status])                        退出一个进程(状态:退出提示字符串)
字符串方法补充:
    S.splitlines  按行分隔

os模块补充:
os.path.exists(file) 判断一个文件是否存在
os.remove(file) 删除文件
os.unlink(file) 删除文件
pid = os.fork() 创建进程 失败-1 成功0
os.getpid() 获取进程的PID号
os.getppid() 获取父进程的PID
os.exit(status) 退出一个进程(状态:整数 默认0)
pid,status = os.wait() 塞等待处理子进程的退出
os.WEXITSTATUS(status) 获取原来退出状态
pid,status = os.waitpid(pid,option) 阻塞等待处理子进程的退出
os.path.getsize('./1.txt')                   读取文件的大小
os.kill(pid,sig) 发送一个信号给某个进程
os.listdir(path) 获取指定目录文件列表
os.path.isfile()  判断一个 文件是否为普通文件
os.path.isdir()  判断一个文件是否为目录 


传输层服务:
    面向连接的传输服务(tcp协议):
        传输特征:
          可靠的数据传输:
            可靠性:无失序、无差错、无重复、无丢失、无重复
        在数据传输前和传输后需要建立连接和断开链接
          面向传输服务建立连接的过程:‘三次握手’
            1.客户端向服务器发送链接请求
            2.服务器接受到请求进行确认,返回确认报文
            3.客户端收到服务器回复最终确认链接
          面向传输服务断开链接的过程:‘四次挥手’
            1.主动方发送报文,告知被动方要断开链接
    2.被动方回复报文,表示已经接受到请求,准备断开
    3.被动方再次发送报文,表示准备处理就绪,可以断开
    4.主动方发送确认报文,断开链接
        应用情况:
    适用于传输较大的内容或文件,网络良好,
    需要保证传输可靠性的情况
    e.g.  信息聊天,文件上传下载,邮件,网页获取

    面向无连接的传输服务(udp协议):
        不保证传输的可靠性
没有建立连接和断开的过程
数据的收发比较自由
适用情况: 
    网络情况较差,对可靠性要求不高,收发消息的两端
    e.g.:网络视频,群聊,广播等


收发函数特性:
     recv特征:
       如果建立的另一端链接被断开, 则recv立即返回空字符串
       recv是从接受缓冲区取出内容,当缓冲区为空则阻塞
       recv如果一次接受不完缓冲区的内容,下次执行会自动接受
     send特征:
        如果发送的另一端不存在则会产生pipe...异常
send是从发送缓冲区发送内容当缓冲区为满则堵塞


http协议:
   超文本传输协议
   用途:
      网站中浏览区器网页的获取,基于网站事物数据传输
      编写基于http协议的数据传输
   特点:
      1.应用层协议,传输层使用tcp服务
      2.简单、灵活,可以使用多种编程语言操作
      3.无状态的协议,既不用记录用户的输入内容
      4.http1.1  ---> http2.0(还没发布)  技术的成熟和稳定性
   http请求(request):
      1.请求格式:
         1)请求行:说明具体的请求类别和内容
          GET    /index.html    /HTTP/1.1
                请求类别   请求内容    协议版本
     2)请求类别:
        GET:获取网络资源
POST:提交一定的附加数据
HEAD:获取相应头
PUT:更新服务器资源
DELETE:删除服务器资源
CONNECT:未使用
TRACE:用于测试
OPTIONS:获取服务器性能信息
2.请求头:对请求的具体描述
     Accept:text/html
        每一个键值对占一行,描述了一个特定信息
3.空行
4.请求体:具体的参数或提交的内容
          get参数或者post提交的内容
   http响应(response):
      1.响应格式:
        1)响应行:反馈具体的响应情况
          HTTP/1.1     20       OK
  版本协议   响应码   附加信息
    3)响应码:
       1xx:提示信息,表示请求已经接收
       2xx:响应成功
       3xx:响应需要定向
       4xx:客户端错误
       5xx:服务器端错误
3)常见响应码:
   200  成功
   404  请求内容不存在
   401  没有访问权限
   500  服务器未知错误
       503  服务器暂时无法执行
      2.响应头:对响应内容的具体描述
      3.空行
      4.响应体:
         将客户端请求内容进行返回


IO多路复用
定义:
通过一个监测,可以同时监控多个IO事件的行为,
当那个IO可以执行,让这个IO事件发生
同时监控多个IO事件,当哪个IO事件准备就绪就执行哪个IO事件
此时形成多个IO时间都可以操作的现象,不必逐个等待执行
IO准备就绪:
IO事件即将发生时的临界状态是不可逆转的
在程序中存在的IO事件中选择要监测的事件
创建监测,将监测的IO事件注册
等待监测的IO事件发生,判断是什么事件
处理相应的IO

poll方法实现IO多路复用:
   1.创建poll对象:
       p = select.poll
   2.注册关注的IO:
       p.register(s, POLLIN | PLLERR)
       不关注:
          p.unregister(s)
       事件类别:
          POLLIN  POLLOUT  POLLERR  POLLHUP   POLLPRI
          rlist    wlist    xlist     断开   紧急处理 
   3.监控IO:
       events = p.poll()
       功能:监控关注的IO事件
       返回值:
           返回发生IO事件
   events是一个列表[(fileno, evnet), (), ()....]
   每个就绪IO对应一个元组(描述符,就绪事件)
       IO地图:{s.fileno():s}
   4.处理IO事件

位运算:
   按照二进制位进行位运算操作
   & 按为与   |按位或   ^按位异或

   << 左异    >>右移

   11  1011
   14  1110

   &   1010  有0得0
   |   1111  有1得1
   ^   0101  相同为0不同为1
  
   11 << 2  == 44   右侧补零(乘2乘2次)
   14 >> 2  == 3    挤掉右侧的数字(地板除2除2次)
使用:
    1.在低层硬件时操作寄存器
    2.做标志位的过滤



多任务编程:
    意义:
充分利用计算机资源,同时运行多个任务,
提高程序整体的运行效率
    定义:
通过程序利用计算机的多个核心达到同时执行多个任务的目的
因此达到提升程序运行效率的目的
    实施方案:
多进程编程
多线程编程
    并行:
        多个计算机核心在同时处理多个任务,
这时多个任务之间是并行关系
     并发:
        同时运行多个任务,内核在多个任务之间的不断切换,
达到多个任务都会执行的处理效果
此时多个任务之间的并发关系

程序:
    是一个可执行文件,是静态的,只占有磁盘
    不占用计算机运行资源
进程:
    程序在计算机中的一次执行过程
    是一个动态过程,占有一定的计算机资源
    有一定的生命周期
注:
    同一个程序不同的运行过程是不同的进程,
    因为分配的资源和生命周期都不同

进程的创建过程:
    1.用户启动一个程序,或是调用接口发起进程创建
    2.操作系统接收用户请求分配计算机资源创建进程
    3.操作系统将一定状态的进程提供给用户使用
    4.用户利用操作提供的进程完成任务

CPU时间片:
    如果有个进程占有CPU此时我们称为该进程占有CPU的时间片
    多个进程任务或轮流占有CPU时间片并形成并发效果
  
进程信息(process)
    PCB(进程控制块):
         进程创建后 会自动在内存中产生一个空间存放进程信息
    进程信息:
        进程ID 进程占有内存的位置  创建时间、创建位置
查看系统进程信息:ps -aux
    PID(process ID):
      在操作系统中每个进程都有唯一的PID值是由系统分配的
进程特征:
    进程是操作系统分配资源的最小单元
    每个进程拥有自己独立的运行空间(4个G的虚拟内存空间)
    进程之间相互独立各不影响
进程的状态:
    三态:
    就绪状态:
         进程具备执行条件,等待系统分配处理器资源进入运行态
    运行态:
         进程占有CPU处于运行状态
    等待态:
         进程暂时不具备运行条件,需要阻塞等待

    五态:
         在三态的基础上增加新建和终止态 
新建:
   创建一个新的程序,获取系统资源的过程
终止:
   进程执行结束,释放资源的过程

ps -aux ---> STAT表示进程状态:
    D  等待态  阻塞  不可中断等待态
    S  等待态  睡眠  可中断等待态
    T  等待态  暂停  暂停执行
    R  运行态(就绪态)
    Z  僵尸
      +  前台进程(在终端运行)
      <  有较高优先级的进程
      N  较低优先级的进程
      s  回话组
      l  有进程链接
进程的优先级:
    top 查看进程运行态优先级
    取值范围:-20~19   -20最高
    nice:
       以指定的优先级运行一个程序
       nice -9 ./hello.py  以9的优先级运行
       sudo nice --9 ./hello.py 以-9优先级运行

    首行添加 #! /usr/bin/python3  指定执行器
      执行:./hello.py
    修改程序权限添加可执行权限
         chmod 775 hello.py

孤儿进程 : 
当父进程先于子进程退出,此时子进程就会成为孤儿进程。
    * 孤儿进程会被系统指定进程收养,即系统进程会成为孤儿
      进程新的父进程。系统进程会自动处理孤儿进程退出状态

僵尸进程 : 
子进程先于父进程退出,父进程没有处理子进程的退出状态,此时子进程就会成为僵尸进程
* 僵尸进程会滞留部分PCB信息在内存中,大量的僵尸进
  程会消耗系统的内存资源,所以要尽量避免僵尸进程产生

如何避免僵尸进程产生?
* 父进程先退出
* 父进程处理子进程退出状态
* 创建二级子进程

进程池技术:
    产生原因:
    如果有大量的任务需要多进程完成,而调用周期比较短且需要频繁创建
此时可能产生大量进程频繁创建销毁的情况  消耗计算机资源较大
    使用方法:
    1.创建进程池,在池内放入适当数量的进程
2.将事件封装成函数。放入到进程池
3.事件不断运行,直到所有放入进程池事件运行完成
4.关闭进程池,回收进程
同步互斥机制
    目的:
       解决对共有资源产生的资源争夺
    临界资源:
         多个进程或线程都可以操作的资源
    临界区:
        操作临界资源的代码段
    同步:
    同步是一种合作关系,为完成某个任务,
多进程或者多个线程之间形成的一种协调
按照约定执行,相互告知,共同完成任务
    互斥:
    互斥是一种制约关系,当一个进程或者线程
进入临界区操作资源时采用上锁的方式,
阻止其他进程操作,直到解锁后才能让出资源
多线程:
    什么是线程(thread)?
      线程也是一种多任务编程方式,可以使用计算机的多核资源
      线程被称为轻量级的进程
    线程的特征:
      1.一个进程可以包含多个线程
      2.线程是计算机内核使用的最小单位
      3.线程也是一个运行过程,也要消耗计算机资源
      4.多个线程共享共用进程的资源
      5.线程也有自己的特征属性,TID、指令集、线程栈
      6.多个线程之间独立运行互不干扰 空间不独立(都消耗进程空间)
      7.线程的创建删除消耗的资源要小于进程 线程/进程(1/20)
线程通信:
               多个线程共用线程空间,所以进程的全局变量对进程内线程均可见
               线程的通信方法就是使用去全局变量通信
       注:
              线程间使用全局变量进程通信时,全局变量为共享资源
               往往需要同步互斥机制



进程和线程的区别和联系:
    1.两者都是多任务编程的方式  都能够使用计算机的多核
    2.进程的创建和删除要比线程消耗更多的计算机资源
    3.进程空间独立,数据安全性好,有专门的进程间的通信方法
    4.线程使用全局变量,更加简单,但需要同步互斥操作
    5.一个进程可以包含多个线程,线程共享进程空间资源
    6.进程线程都独立执行,有自己的特有属性

使用情况:
    1.一个进程中并发任务比较多,比较简单,适合使用多线程
    2.如果数据程序比较复杂,特别是可能多个任务通信比较多的时候
      要考虑使用线程同步互斥的复杂性
    3.多个任务存在明显差异,和功能分离的时候没有必要一定写入到一个进程中
    4.使用Python要考虑到GIL的问题


Pyhthon线程GIL问题:
    GIL (全局解释器锁)
    Python --->支持线程操作--->出现IO同步互斥--->加锁--->超级锁,给解释器加锁
    后果:
        同一时刻一个解释器只解释一个线程 
        此时其他线程需要等待。大大降低了Python线程的执行效率
        只能实现并发不能实现并行

Python GIL问题解决方案:
    1.修改c解释器
    2.尽量使用多进程进行并行操作
    3.Python线程尽量用在高延迟多阻塞的IO情形
    3.不使用CPython   使用C#、JAVA 做的得解释器


网络服务器基础:
    循环服务器::
        单进程程序,循环接受客户请求,处理请求,处理完毕后再接受下一次请求
        特点:
            每次只能处理一个客户端请求,如果客户端长期占有服务器则无法处理其他客户端
            请求
        优点:
            实现简单,占用资源少
        缺点:
            无法同时处理多个客户端,体验差
        使用情况:
            任务短暂,可以快速完成,udp比tcp更适合循环
    并发服务器:
        能够同时处理多个客户端任务请求
        IO并发:
            IO多路复用 协程
            优点:
                可以实现IO并发操作,占用系统资源少
            缺点:
                不能够监控CPU密集的情况,并不能有长期阻塞
        多进程/线程并发:
            为每个客户端单独提供一个进程或线程,处理客户端请求
            优点:
                客户端可以长期占有服务器
            缺点:
                消耗计算机资源比较多

网友评论

登录后评论
0/500
评论
巴黎香榭
+ 关注