在開始一次連線之前,要先創建一個socket變數,可以利用socket模組內的socket函式來完成。我們要先告訴socket函示我們要創建的連接類型是什麼,而python中支援的連線類型大概有以下幾種:
- socket.AF_UNIX:本機通訊
- socket.AF_INET:網路通訊
- socket.AF_INET6:IPv6的網路通訊
- socket.SOCK_STREAM:TCP協定
- socket.SOCK_DGRAM:UDP協定
- socket.SOCK_RAW:不使用任何協定解析(通常用在封包分析上)
- socket.SOCK_SEQPACKET:建立一個可靠的連結(不常用,僅linux系統支援)
上面用螢光標記的是比較常用的連接類型。如果我們要創建一個TCP連接的socket,可以這樣寫:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
而UDP連接的socket可以這樣創建:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
這邊要注意,我們在發送數據時,只能發送字串,不能發送列表等帶有資料型別的變數。
伺服器端函數
以下的s假設為一個socket變數
- s.bind(address):綁定在指定地址上,address的格式是一個tuple:(host, port),host是本機IP、port是要綁定的端口。
- s.listen(backlog):等待連線,backlog是允許最大的連線數,像s.listen(3)就只允許3個人連進來,超過者拒絕連線。
- s.accept():連接成功後,會回傳一個tuple:(conn, address),conn是新的socket,可以用來收發資料;address是連接客戶端的IP位址。
客戶端函數
- s.connect(address):連結伺服器,address的格式是一個tuple:(host, port),host是伺服器端IP、port是伺服器端綁定的端口。如果連線失敗,會傳回socket.error。
- s.connect_ex(address):功能跟connect(address)一樣,只是如果成功連線會回傳0,失敗會回傳error的數值。
都可以使用的函數
- s.recv(bufsize[, flag]):接收TCP連接的資料,資料以字串形式回傳bufsize是要接收的最大資料量。flag提供其他訊息,但通常可以忽略。
- s.send(string[, flag]):以TCP協定發送資料,會回傳要發送的資料量。
- s.sendall(string[, flag]):嘗試一次完整發送整個string,失敗會拋出例外。
- s.recvfrom(bufsize[, flag]):接收UDP資料,會回傳一個tuple:(data, address),data是資料,而address是發送端的IP。
- s.sendto(string[, flag], address):發送UDP資料,address的格式是一個tuple:(ipaddr, port),指定伺服器發送,和send一樣,會回傳要發送的量。
- s.close():關閉socket。
- s.getpeername():回傳socket另一端的地址及端口,型態通常是一個tuple:(ipaddr, port)。
- s.getsockname():回傳socket自己的地址及端口,型態通常是一個tuple:(ipaddr, port)。
- s.setsockopt(level, optname, value):把s的optname設置為value。
- s.getsockopt(level, optname[, buflen]):取得在s中,optname的值。
- s.settimeout(timeout):設定判斷連線逾時的秒數,timeout的值是浮點數,單位為秒,若設定為None則永遠不會超時。
- s.gettimeout():回傳超時設定,單位為秒,如果沒有設定就會回傳None。
- s.fileno():返回s的文件描述
- s.setblocking(flag):如果flag是0,則設置為非阻塞模式,否則設置為阻塞模式(預設值)。 非阻塞模式下,如果調用recv()沒有發現任何資料,或send()調用無法立即發送資料,那麼將拋出socket.error例外。
- s.makefile():創建一個與s相關的文件
接下來給一組範例演示一下吧:
伺服端
import socket HOST = '192.168.1.100'#設定要綁定的地址 PORT = 8001 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#創建socket s.bind((HOST, PORT))#綁定 s.listen(5)#監聽 #進入無窮迴圈等代客戶端連線 while True: conn, addr = s.accept() print 'Connected by ', addr #連線成功後,不斷接收並印出資料,並回傳收到 while True: data = conn.recv(1024) print data conn.send("server received you message.") # conn.close()
客戶端
import socket #伺服器資訊 HOST = '192.168.1.100' PORT = 8001 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#創建socket s.connect((HOST, PORT)) #不斷發送使用者輸入的訊息給伺服器 while True: msg = raw_input("Please input msg:") s.send(msg)#發送 data = s.recv(1024)#接收伺服器訊息 print data #s.close()
服務端:Github下載
0 意見