Python提供了兩個級別的訪問網路服務。 在低級別,可以訪問底層操作系統中的基本套接字支持,這允許您實現面向連接和無連接協議的客戶端和服務器。
Python還具有提供對特定應用級網路協議(如FTP,HTTP等)的更高級別訪問的庫。
本章將瞭解和學習網路中最著名的概念 - 套接字編程。
1.什麼是套接字?
套接字(Sockets)是雙向通信通道的端點。 套接字可以在一個進程內,在同一機器上的進程之間,或者在不同主機的進程之間進行通信,主機可以是任何一臺有連接互聯網的機器。
套接字可以通過多種不同的通道類型實現:Unix域套接字,TCP,UDP等。 套接字形檔提供了處理公共傳輸的特定類,以及一個用於處理其餘部分的通用介面。
套接字有自己的術語 -
domain - 用作傳輸機制的協議族。這些值是常量,例如:
AF_INET
,PF_INET
,PF_UNIX
,PF_X25
等。type - 兩個端點之間的通信類型,通常用於面向連接的協議的
SOCK_STREAM
和用於無連接協議的SOCK_DGRAM
。- protocol - 通常為
0
,這可以用於標識域和類型中的協議的變體。 - hostname - 網路介面的識別字 -
- 一個字串,可以是一個主機名,一個有四個點符號的IP地址,或一個冒號中的IPV6地址(可能是點)符號。
- 一個字串“
<broadcast>
”,它指定一個INADDR_BROADCAST
地址。 - 零長度字串,指定
INADDR_ANY
,或 - 整數,以主機位元組順序解釋為二進位地址。
- port - 每個伺服器監聽一個或多個端口的客戶端的調用。端口可能是
Fixnum
端口號,包含端口號的字串或服務名稱。
2. socket模組
要創建套接字,必須使用套接字模塊中的socket.socket()
函數,該函數具有一般語法 -
s = socket.socket (socket_family, socket_type, protocol = 0)
這裏是上述參數的描述 -
- socket_family - 它的值可以是:
AF_UNIX
或AF_INET
,如前所述。 - socket_type - 它的值可以是:
SOCK_STREAM
或SOCK_DGRAM
。 - protocol - 這通常被省略,默認為
0
。
當創建了套接字對象這後,就可以使用所需的函數來創建客戶端或伺服器程式。 以下是所需函數的列表:
伺服器套接字方法
編號 | 方法 | 描述 |
---|---|---|
1 | s.bind() |
此方法將地址(主機名,端口號對)綁定到套接字。 |
2 | s.listen() |
此方法設置並啟動TCP偵聽器。 |
3 | s.accept() |
這被動地接受TCP客戶端連接,等待直到連接到達(阻塞)。 |
客戶端套接字方法
編號 | 方法 | 描述 |
---|---|---|
1 | s.connect() |
此方法主動啟動TCP伺服器連接。 |
通用套接字方法
編號 | 方法 | 描述 |
---|---|---|
1 | s.recv() |
此方法接收TCP消息。 |
2 | s.send() |
該方法發送TCP消息 |
3 | s.recvfrom() |
此方法接收UDP消息 |
4 | s.sendto() |
此方法發送UDP消息 |
5 | s.close() |
此方法關閉套接字 |
6 | socket.gethostname() |
返回主機名 |
3.一個簡單的伺服器
要編寫互聯網伺服器,可使用socket
模組中可用的socket()
來創建套接字對象。 然後使用套接字對象調用其他函數來設置套接字伺服器。
現在調用bind(hostname,port)
函數來指定主機上服務的端口。
接下來,調用返回對象的accept()
方法。 此方法在您指定的端口等待客戶端連接,連接成功後返回一個連接(connection
)對象,該對象表示與該客戶端的連接。
#!/usr/bin/python3 # This is server.py file
import socket
# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8088
# bind to the port
serversocket.bind((host, port))
print("Server start at port: 8088")
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
msg='Thank you for connecting'+ "\r\n"
clientsocket.send(msg.encode('ascii'))
clientsocket.close()
4.一個簡單的客戶端
下麵接著編寫一個非常簡單的客戶端程式,打開與給定端口8088
與上面的伺服器程式主機的連接。 使用Python的socket
模組功能創建套接字客戶端非常簡單。
socket.connect(hosname,port)
函數打開hostname
上的port
的TCP連接。當打開了一個套接字,就可以像任何IO對象一樣讀取它。 完成後,請記住關閉它,就像關閉檔一樣。
示例
以下代碼是連接到給定主機和端口的非常簡單的客戶端,從套接字讀取任何可用數據,然後退出 -
#!/usr/bin/python3 # This is client.py file
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8088
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
msg = s.recv(1024)
s.close()
print (msg.decode('ascii'))
現在在後臺運行先運行:server.py
,然後運行上面的client.py
來查看結果,如果程式沒有錯誤,那麼應該得到類似以下以結果 -
5. Python互聯網模組
Python網路/互聯網編程中的一些重要模組的列表如下:
協議 | 通用功能 | 端口號 | 對應Python模組 |
---|---|---|---|
HTTP | 網頁服務 | 80 | httplib, urllib, xmlrpclib |
NNTP | Usenet新聞 | 119 | nntplib |
FTP | 檔傳輸 | 20 | ftplib, urllib |
SMTP | 發送郵件 | 25 | smtplib |
POP3 | 獲取電子郵件 | 110 | poplib |
IMAP4 | 獲取電子郵件 | 143 | imaplib |
Telnet | 命令行 | 23 | telnetlib |
Gopher | 文檔傳輸 | 70 | gopherlib, urllib |
請檢查上述所有庫,以使用FTP,SMTP,POP和IMAP協議。
進一步閱讀
這是Socket編程的一個快速開始。 這是一個廣闊的話題。 建議通過以下鏈接查找更多詳細資訊 -