一、網絡基礎
網絡由下往上分為:物理層、數據鏈路層、網絡怪、傳輸層、會話層、表示層和應用層。
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對象方法:
1 bind('127.0.0.1',1051) 綁定ip地址和端口,如果地址為空則表示本機; 2 listen(backlog) 監聽所有socket對象創建的連接,backlog指定連接隊列數,最小為1,最大一般為5; 3 connect(address) 4 connect_ex(address) 兩個都可以連接到服務端,不同的是第一個返回一個錯誤,第二個返回一個異常; 5 accept() 接收來自客戶端的數據,返回一個新的socket對象和客戶端地址; 6 recv(bufsize,flags) 僅返回所接收的字符串;bufsize指定接收緩沖區的大小,flags為可選參數,表示接收標志; 7 recvfrom(bufsize,flags) 返回所接收的字符串和地址; 8 send(string,flags) 向已經連接的socket發送數據; 9 sendall(string,flags) 與send不同的是將會一直發送完全部數據; 10 sendto(string,flags,address)可以向一個未連接的socket發送數據; 11 makefile(mode,bufsize) 將socket關聯到文件對象上,兩個參數都是可選的,mode文件模式,bufsize緩沖區大小; 12 close() 完成通信后,應使用close方法關閉網絡連接;
1 # 服務器端實例 2 import socket
3 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 4 sock.bind('127.0.0.1',20178) 5 sock.listen(5) 6 conn,address = sock.accept() 7 print('connect by ',address) 8 while True: 9 data = conn.recv(100) 10 if not data:break 11 print(data) 12 conn.send("anydata") 13 sock.close()
1 #客戶端實例 2 import socket
3 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #與服務端相同 4 sock.connect('127.0.0.1',20178) 5 sock.send("data") 6 data = sock.recv(98) 7 print('recieved ',data) 8 sock.close()
可用select模塊來實現多個並發的交互
1 # 服務端實例 2 import socket 3 import select 4 import queue 5 6 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 7 sock.setblocking(False) #設置為非阻塞服務 8 sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 9 sock.bind('127.0.0.1',20178) 10 sock.listen(10) 11 rlists = [sock] 12 wlists = [] 13 msg_que = {} 14 timeout = 20 15 16 while rlists: 17 rs,ws,es = select.select(rlists,wlists,rlists,timeout) 18 if not (rs or ws or es): 19 print('timeout...') 20 break 21 for s in rs: 22 if s is sock: 23 conn,address = s.accept() 24 conn.setblocking(False) 25 rlists.append(conn) 26 msg_que[conn] = queue.Queue() 27 else: 28 data = s.recv(1024) 29 if data: 30 print(data) 31 msg_que[s].put(data) 32 if s not in wlists: 33 wlists.append(s) 34 else: 35 if s in wlists: 36 wlists.remove(s) 37 rlists.remove(s) 38 s.close() 39 del msg_que[s] 40 for s in ws: 41 try: 42 msg = msg_que[s].get_nowait() 43 except queue.Empty: 44 wlists.remove(s) 45 for s in es: 46 print('except ',s.getpeername()) 47 if s in rlists: 48 rlists.remove(s) 49 if s in wlists: 50 wlists.remove(s) 51 s.close() 52 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連接對象,此對象的方法有:
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模塊收發郵件
