Python Socket的介紹與簡單使用
Socket 簡介
Socket子產品的主要目的就是幫助在網絡上的兩個程式之間建立資訊通道。在python中提供了兩個基本的Socket子產品:服務端Socket和用戶端Socket。當建立了一個服務端Socket之後,這個Socket就會在本機的一個端口上等待連接配接,用戶端Socket會通路這個端口,當兩者完成連接配接之後就能夠進行互動了。在使用Socket進行程式設計時,需要先執行個體化一個Scoket類。
使用Socker建立服務端的思路主要是首先執行個體化一個 Socket類,然後開始循環監聽,一直可以接收來自用戶端的連接配接。成功建立連接配接之後,接收用戶端發來的資料,并再向用戶端發送資料,傳輸完畢之後,關閉這次連接配接。
使用Socket建立用戶端則要簡單得多,在執行個體化一個Socket類之後,連接配接一個遠端的位址,這個位址由IP和端口組成。成功建立連接配接之後,開始發送和接收資料,傳輸完畢之後,關閉這次連接配接。
基本用法
一、Socket的執行個體化
執行個體化的格式為:
其中第一個參數family表示位址族,常用的協定族有:AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE等,預設值為AF_INET,通常使用這個即可。
第二個參數表示Socket類型,這裡使用的值有三個:SOCK_STREAM、SOCK_DGRAM、SOCK_RAW。
SOCK_STREAM是TCP類型,保證資料順序以及可靠性;
SOCK_DGRAM是UDP類型,不保證資料接收的順序,非可靠連接配接;
SOCK_RAW是原始類型,允許對底層協定如IP、ICMP進行直接通路,基本不會用到。
預設值是第一個。
第三個參數是指定協定,這個是可選的,通常指派為0,由系統選擇。
例如想初始化一個TCP類型的Socket,語句如下:
x = socket.socket()
這條語句相當于:
x = socket.socket(sokcet.AF_INET, socket.SOCK_STREAM)
因為這裡都是預設值是以可以省略掉
而如果想初始化一個UDP類型,則語句如下:
二、Socket常用的函數
當成功初始化一個 Socket之後,就可以使用Socket類所提供的函數。Socket類中主要提供如下所示常用的函數:
bind():這個函數由服務端Socket調用,會将之前建立Socker與指定的IP位址和端口進行綁定。如果之前使用了AF_INET初始化Socket,那麼這裡可以使用元組(host, port) 的形式表示位址。
例如,要将剛才建立的Socket套接字綁定到本機的2345端口,就可以使用如下語句:
listen():這個函數用于在使用TCP的服務端開啟監聽模式。這個函數可以使用個參數來指定可以挂起的最大連接配接數量。這個參數的值最小為1,般設定為5。
例如,要在服務端開啟一個監聽, 可以使用如下語句:
accept():這個函數用于在使用TCP的服務端接收連接配接,一般是阻塞态。接受TCP連接配接并傳回(conn,adresse), 其中,conn 是新的套接字對象,可以用來接收和發送資料; address是連接配接用戶端的位址。
以上三個函數是用于服務端的Socket 函數,,,
connect():這個兩數用于在使用TCP的用戶端去連接配接服務端時使用,使用的參數是一個元組,形式為(hostname, port)。
例如,在用戶端程式初始化了一個Socker 之後,就可以使用這個函數去連接配接到服務端。例如,現在要連接配接本機的2345端口,可以使用如下語句:
send():這個函數用于在使用TCP時發送資料,完整的形式為
send(string[,flag])
利用這個函數可以将string代表的資料發送到已經連接配接的Socket,傳回值是發送位元組的數量。但是可能未将指定的内容全部發送。
sendall():這個函數與send()相類似,也是用于在使用TCP時發送資料,完整的形式為sendall(string[,falg]),與send()的差別是完整發送TCP資料。将string中的資料發送到連接配接的套接字,但在傳回之前會嘗試發送所有資料。成功傳回None,失敗則抛出異常。
例如,使用這個函數發送一段字元到Socket,可以使用如下語句:
recv():這個兩數用于在使用TCP時接收資料,完整的形式為recv(bufsize[,flag]),接收Soker的資料。資料以字元串形式傳回,bufsize指定最多可以接收的數量,flag這個參數一般不會使用。
例如,通過這個函數接收一段長度為1024的字元Socket,可以使用如下語句:
sendto():這個函數用于在使用UDP時發送資料,完整的形式為sendto(string[,flag],address),傳回值是發送的位元組數。address 是形式為(ipaddr,port) 的元組,指定遠端位址。
recvfrom(): UDP專用,接收資料,傳回資料遠端的IP位址和端口,但傳回值是(data,address)。其中,data 是包含接收資料的字元事,adress 是發送資料的套接字位址。
closc():關閉socket。
使用Socket編寫一個簡單的服務端和用戶端
服務端:
import socket
x = socket.socket()
x.bind(("127.0.0.1",1234))
x.listen(5)
while True:
conn,address = x.accept()
print("A new connent from ", address)
conn.sendall(bytes("Hello! A_dmin!!",encoding="utf-8"))
conn.close()
用戶端:
import socket
x = socket.socket()
x.connect(("127.0.0.1",1234))
data = x.recv(1024)
x.close()
print("Received " + repr(data))
效果如下:
