socket模塊簡介
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。socket通常被叫做“套接字”,用於描述IP地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個端口上,不同的端口對應於不同的服務。python中socket模塊為操作系統的socket實現提供了一個python接口。
socket模塊方法及實例
1.socket.socket(family,type)
創建並返回一個新的socket對象,這也是socket最常用的方法。
family參數指的是host的種類:
AF_UNIX:也叫AF_LOCAL,基於本地文件的
AF_NETLINK:這是linux系統支持的一種套接字
AF_INET:這個套接字是基於網絡的,對於IPV4協議的TCP和UDP(常用)
AF_INET6:這個套接字是基於網絡的,對於IPV6協議的TCP和UDP
type參數指的是套接字類型:
SOCK_STREAM:流套接字,使用TCP socket(常用)
SOCK_DGRAM:數據包問套接字,使用UDP socket(常用)
SOCK_RAW:raw套接字
舉例:網絡使用ipv4,協議選擇tcp連接
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
2.s=socket.socket(family,type)的實例方法
(1)s.bind((address,port))
將socket綁定到一個地址和端口上,通常用於socket服務端
address必須是一個雙元素元組,((host,port)),主機名或者IP地址+端口號。如果端口號正在被使用或者主機名或IP地址錯誤,則引發socket.error異常。
端口號的使用是有限制的,在linux或者unix之中只有系統管理員才能使用1024以下的端口,這些端口號用於標准服務。
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.bind(("172.16.0.183",555))
(2)s.accept()
返回一個客戶機socket,帶有客戶機端的地址信息。
調用accept方法的時候,socket會進入阻塞狀態。客戶請求連接時,方法建立連接並返回服務器。
accept方法返回一個雙元素元組,形如(connection,address)。第一個元素是新的socket對象,第二個元素是客戶的IP地址。
當一個連接close之后,可以接着調用accept繼續接收從客戶端發來的連接請求,因為listen讓服務器一直處於監聽的狀態。
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.bind(("172.16.0.183",555))
>>> s.listen(10)
>>> connection,address=s.accept()#開啟這個之后,socket會進入阻塞狀態,並把獲取的connection和客戶端的ip賦值給前面的變量connection和address
>>> print connection
<socket._socketobject object at 0x01DDDCE0>
>>> print address
('172.16.0.183', 21586)
>>>
(3)s.listen(backlog)
將socket設置成監聽模式,可以監聽backlog外來的連接請求,讓服務器開始監聽客戶端發來的連接請求
這個方法設置服務器為監聽狀態,backlog制定了最多的連接數,至少為1.接到連接請求后,這些請求必須排隊,如果隊列達到backlog的數值,則拒絕接下來的連接請求。
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.bind(("172.16.0.183",555))
>>> s.listen(10)
4)s.connect((address,port))
將socket連接到定義的主機和端口上,通常用於socket客戶端
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.connect(("172.16.0.183"),555)#錯誤格式
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
TypeError: connect() takes exactly one argument (2 given)
>>> s.connect(("172.16.0.183",555))
(5)s.recv(buflen[,flags])
從socket中接收數據,最多接收buflen個字符,一般填寫1024個
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.connect(("172.16.0.183",555))
>>> data=s.recv(1024)
(6)s.send(data[,flags])
通過socket發送指定的數據
>>> import socket
>>> s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.bind(("172.16.0.183",555))
>>> s.listen(10)
>>> connection,address=s.accept()
>>> print connection
<socket._socketobject object at 0x01DDDCE0>
>>> print address
('172.16.0.183', 21586)
>>> s.send('hello,I am lybbn.cn')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 10057] 由於套接字沒有連接並且(當使用一個 sendto 調用發送數
據報套接字時)
由上可見,s.send()發送數據的時候需要先建立socket連接,不然會出現error
使用recv方法和send方法發送和接受消息。發送和接收都是采用的字符串的形式。send方法返回已發送的字符個數。調用recv的時候,必須制定一個整數來控制本次調用所接受的最大的數據量。
recv方法接收數據時會進入阻塞狀態,最后返回一個字符串,表示收到的數據。如果發送數據超過recv所允許,數據會被截斷。多余的數據將緩沖於接收端。以后調用recv時,多余的數據會從緩沖區刪除。
(7)s.close()
關閉socket連接
傳輸結束,通過調用close方法關閉連接
一個簡單的socket服務端舉例
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',10000))
s.listen(5)
while True:
cs,address=s.accept() #讓服務器可以在close之后接收其他客戶端的連接請求
print('got connected from'+address)
cs.send('I have got your socket')
data = cs.recv(1024)
cs.close
一個簡單的socket客戶端舉例
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect('127.0.0.1',10000)
data=s.recv(1024)
s.send('this is a connection from client')
print('The data received is '+data)
s.close()