1. 程式人生 > >python中socket模組詳解

python中socket模組詳解

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()