Python中常用網路程式設計模組

嗨学编程發表於2024-03-19

一、網路基礎

網路由下往上分為:物理層、資料鏈路層、網路怪、傳輸層、會話層、表示層和應用層。

TCP/IP協議是傳輸層協議,主要解決資料如何在網路中傳輸;socket則是對TCP/IP協議的封裝,它本身不是協議,而是一個呼叫介面;

HTTP、FTP是應用協議,主要解決如何包裝資料;

TCP連線的三次握手:

  • 第一次握手:客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
  • 第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
  • 第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。

利用Socket建立網路連線的步驟(一對套接字連線過程):
1、伺服器監聽:伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連線的狀態,實時監控網路狀態,等待客戶端的連線請求。
2、客戶端請求:指客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。
  為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連線請求。
  3、連線確認:當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求時,就響應客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連線。
而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。

TCP和UDP的區別:

  • TCP是面向連線的,連線經過了三次握手,很大程度的保證了連線的可靠性;
    -UDP傳送資料前並不與對方建立連線,對收到的資料也不傳送觸診訊號,因此UDP的開銷更小,資料傳輸速率更高。QQ是就採用的UPD協議傳輸,而相似的MSN採用的是TCP協議傳輸。

二、socket模組

網路服務都是建立在socket基礎之上的,socket是網路連線端點,是網路的基礎;每個socket都被繫結到指定的IP和埠上;

1、首先使用socket(family=AF_INET,type=SOCK_STREAM,proto)函式建立一個物件;

family 地址引數,還可以有AF_INET6,AF_UNIX;
type socket型別;
proto 協議型別,可選引數

建立成功後用bind('127.0.0.1',1051)繫結ip地址和埠,如果地址為空則表示本機;

2、socket物件方法:

bind('127.0.0.1',1051)    繫結ip地址和埠,如果地址為空則表示本機;
    listen(backlog)          監聽所有socket物件建立的連線,backlog指定連線佇列數,最小為1,最大一般為5;
    connect(address)
    connect_ex(address)      兩個都可以連線到服務端,不同的是第一個返回一個錯誤,第二個返回一個異常;
    accept()              接收來自客戶端的資料,返回一個新的socket物件和客戶端地址;
    recv(bufsize,flags)      僅返回所接收的字串;bufsize指定接收緩衝區的大小,flags為可選引數,表示接收標誌;
    recvfrom(bufsize,flags)    返回所接收的字串和地址;
    send(string,flags)       向已經連線的socket傳送資料;
    sendall(string,flags)      與send不同的是將會一直髮送完全部資料;
    sendto(string,flags,address)可以向一個未連線的socket傳送資料;
    makefile(mode,bufsize)     將socket關聯到檔案物件上,兩個引數都是可選的,mode檔案模式,bufsize緩衝區大小;
    close()                 完成通訊後,應使用close方法關閉網路連線;

伺服器端例項

import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind('127.0.0.1',20178)
sock.listen(5)
conn,address = sock.accept()
print('connect by ',address)
while True:
    data = conn.recv(100)
    if not data:break
    print(data)
    conn.send("anydata")
sock.close()

客戶端例項

import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #與服務端相同
sock.connect('127.0.0.1',20178)
sock.send("data")
data = sock.recv(98)
print('recieved ',data)
sock.close()

可用select模組來實現多個併發的互動

# 服務端例項
import socket
import select
import queue

sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setblocking(False)   #設定為非阻塞服務
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind('127.0.0.1',20178)
sock.listen(10)
rlists = [sock]
wlists = []
msg_que = {}
timeout = 20

while rlists:
    rs,ws,es = select.select(rlists,wlists,rlists,timeout)
    if not (rs or ws or es):
        print('timeout...')
        break
    for s in rs:
        if s is sock:
            conn,address = s.accept()
            conn.setblocking(False)
            rlists.append(conn)
            msg_que[conn] = queue.Queue()
        else:
            data = s.recv(1024)
            if data:
                print(data)
                msg_que[s].put(data)
                if s not in wlists:
                    wlists.append(s)
            else:
                if s in wlists:
                    wlists.remove(s)
                rlists.remove(s)
                s.close()
                del msg_que[s]
    for s in ws:
        try:
            msg = msg_que[s].get_nowait()
        except queue.Empty:
            wlists.remove(s)
    for s in es:
        print('except ',s.getpeername())
        if s in rlists:
            rlists.remove(s)
        if s in wlists:
            wlists.remove(s)
        s.close()
        del msg_que[s]

三、httplib模組

httplib模組內提供了HTTPConnection物件和HTTPRresponse物件;

當建立一個HTTPConnection物件時可用方法有:

1、request(method,url,body,headers) 向伺服器傳送請求;

  • method 方法,有"GET","POST"等待連線

  • body 傳送的資料

  • headers 傳送的HTTP頭

2、getresponse() 返回一個HTTPResponse物件;

3、close() 關閉與伺服器的連線;

4、send(data) 傳送資料;

5、putrequest(request,selector,skip_host,skip_accep_encoding) 向伺服器傳送請求;

  • request 所傳送的操作;

  • selector 進行操作的URL;

  • skip_host 若為True則禁止自動傳送"POST";

  • skip_accep_encoding 若為True則禁止自動傳送"Accept-Encoding:headers"

6、putheader(headers,argument,...)

  • headers 傳送的HTTP頭;

  • argument 傳送的引數;

7、endheaders()

HTTPResponse 物件方法:

 1、read() 獲得伺服器的響應主體;

 2、getheader(name,default) 獲取伺服器響應的HTTP頭;

 3、version() 檢視HTTP協議的版本;

 4、status() 檢視HTTP協議的狀態;

 5、reason()

四、ftp模組

1、FTP(host,user,passwd,acct) 建立一個FTP連線物件,此物件的方法有:

#學習中遇到問題沒人解答?小編建立了一個Python學習交流群:711312441
FTP(host,user,passwd,acct)    建立一個FTP連線物件
    getwelcome()             獲得FTP伺服器的歡迎資訊
    abort()                   中斷檔案傳輸
    sendcmd(command)          傳送命令,command為一個字串
    voidcmd(command)          傳送命令,但沒有返回值
    retrbinary(command,callback,maxblocksize,rest) 下載檔案(二進位制)
        command            由"RETR 檔名  組成"
        callback          回撥函式
        maxblocksize      每次傳輸最大位元組數
        rest              檔案續傳位置
    retrlines(command,callback)下載檔案(ASCII)
    storbinary(command,file,blocksize)    以二進位制上傳檔案;
    storlines(command,file)    以ASCII形式上傳檔案;
    dir()                   獲取當前目錄的內容列表;
    rename(fromname,toname)    重新命名
    delete(filename)        刪除檔案
    cwd(pathname)            改變當前目錄
    mkd(pathname)            建立目錄
    rmd(dirname)            刪除伺服器上的目錄
    size(filename)           獲取檔案大小
    set_pasv(boolean)        設定傳輸模式
    quit()                
    close()                  關閉伺服器的連線
set_debuglevel(level)         設定除錯級別
connect(host,port)            配置host
login(user,passwd,acct)       登入

附:可使用poplib模組和smtplib模組收發郵件

相關文章