本文介紹使用python進行socket網路程式設計,假設讀者已經具備了基本的網路程式設計知識和python的基本語法知識,本文中的**如果沒有說明則都是執行在python 3.4下。
python的socket功能封裝在socket庫中,要使用socket,記得先import socket,socket庫的詳細介紹參見官方文件。
建立socket
首先建立乙個socket,使用socket庫中得socket函式建立。
import socket
# create an inet, stream socket
s = socket.socket(socket.af_inet, socket.sock_stream)
例子中建立了乙個tcp socket,socket.socket函式的前兩個引數的預設值是socket.af_inet和socket.sock_stream,建立tcp socket時可以直接寫成socket.socket()。
連線伺服器
使用socket的connect函式連線到伺服器,以下幾種引數都是合法的。
傳送資料
傳送資料有兩個方法send和sendall,send不能保證所有的資料都傳送完了,它會返回已傳送資料的長度,程式要迴圈傳送資料直到所有資料都已傳送完畢。
'''
'''def mysend(s, msg):
total_len = len(msg)
total_sent = 0
while total_sent < total_len:
sent = s.send(msg[total_sent:])
if sent == 0:
raise runtimeerror("socket connection broken")
total_sent = sent
sendall能夠保證所有的資料都已傳送完畢,除非傳送過程**現了錯誤,它實際上也是迴圈傳送資料直到所有資料傳送完成。
這裡還要講乙個需要特別注意的地方,從乙個例子開始吧:
s.sendall('test')都是上面講過的東西,沒什麼特別的,分別在python 2和python 3中執行以上的**,結果是:
>>> s.sendall('test')python 2中執行成功。
typeerror: 'str' does not support the buffer inte***cepython 3中卻發生了異常。
同樣的**換個環境卻不能執行了,我沒有寫錯呀,怒砸電腦。好吧,你確實沒寫錯,是環境變了,導致這個結果的變化請移步官方的說明。
接收資料
使用recv函式接收資料:
data = s.recv(4096)
在python 3中返回的是bytes物件,在python 2中返回的是string。注意函式返回的資料長度是小於或者等於引數指定的長度的,要接收到指定長度的資料,需要迴圈接收資料。
def myreceive(s, msglen):
chunks =
bytes_recd = 0
while bytes_recd < msglen:
chunk = s.recv(min(msglen - bytes_recd, 2048))
if chunk == b'':
raise runtimeerror("socket connection broken")
bytes_recd = bytes_recd len(chunk)
return b''.join(chunks)
關閉連線
當連線不再需要時可以使用close關閉socket連線,關閉後的連線不能再進行任何操作。當乙個socket被**時會自動關閉,但是不要依賴這種機制,不需要socket時就主動的close。
服務端服務端程式執行的步驟:
建立服務端socket
將服務端socket繫結到指定的位址和埠
監聽連線
接受客戶端連線
處理客戶端的資料
關閉客戶端連線
乙個簡單的echo server示例:
import socket
host = ''
port = 10022
s = socket.socket(socket.af_inet, socket.sock_stream)
s.bind((host, port))
s.listen(10)
conn, addr = s.accept()
while true:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
conn.close()
客戶端程式:
import socket
host = 'localhost'
port = 10022
s = socket.socket(socket.af_inet, socket.sock_stream)
s.connect((host, port))
s.sendall(b'hello socket')
data = s.recv(1024)
print('received', repr(data))
s.close()
錯誤處理
- socket.error
- socket.herror
- socket.gaierror
- socket.timeout
import socket
host = none
port = 10022
try:
s = socket.socket(socket.af_inet, socket.sock_stream)
s.bind((host, port))
s.listen(10)
except: socket.error as msg:
print(msg)
socket與sock的聯絡
套接字究竟是什麼 如果你知道linux系統中程序間通訊的方式,就應該知道套接字也是其中一種。但套接字特別之處在於它不僅可以用來實現同一臺主機上程序間的通訊,還可以用來實現主機間的程序間的通訊。通訊的雙方各自開啟乙個套接字,套接字之間通過通訊鏈路相連。如果把兩個套接字之間的 連線 比喻成 水管 那麼套...
最基礎的爬蟲
1 引入模組 from urllib import request 2 操作 1 定義目標url base url 請求頭部 request headers headers req request.request base url,headers headers 生成乙個帶headers的reque...
最基礎的Hash
type thash node node record state longint next thash end var a,i longint p thash hash array 0.11 of thash hash表 procedure insert k longint 在雜湊表中插入k va...