Python網絡編程(基礎總結、 入門經典)

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密集的狀況,並不能有長期阻塞
        多進程/線程併發:
            爲每一個客戶端單獨提供一個進程或線程,處理客戶端請求
            優勢:
                客戶端能夠長期佔有服務器
            缺點:
                消耗計算機資源比較多
相關文章
相關標籤/搜索