Python3 網(wǎng)絡(luò)編程

2022-07-01 17:49 更新

Python 提供了兩個(gè)級(jí)別訪問(wèn)的網(wǎng)絡(luò)服務(wù)。:

  • 低級(jí)別的網(wǎng)絡(luò)服務(wù)支持基本的 Socket,它提供了標(biāo)準(zhǔn)的 BSD Sockets API,可以訪問(wèn)底層操作系統(tǒng) Socket 接口的全部方法。
  • 高級(jí)別的網(wǎng)絡(luò)服務(wù)模塊 SocketServer, 它提供了服務(wù)器中心類(lèi),可以簡(jiǎn)化網(wǎng)絡(luò)服務(wù)器的開(kāi)發(fā)。

什么是 Socket?

Socket 又稱(chēng)"套接字",應(yīng)用程序通常通過(guò)"套接字"向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求,使主機(jī)間或者一臺(tái)計(jì)算機(jī)上的進(jìn)程間可以通訊。


socket()函數(shù)

Python 中,我們用 socket()函數(shù)來(lái)創(chuàng)建套接字,語(yǔ)法格式如下:

socket.socket([family[, type[, proto]]])

參數(shù)

  • family: 套接字家族可以使 AF_UNIX 或者 AF_INET
  • type: 套接字類(lèi)型可以根據(jù)是面向連接的還是非連接分為SOCK_STREAMSOCK_DGRAM
  • protocol: 一般不填默認(rèn)為0.

Socket 對(duì)象(內(nèi)建)方法

函數(shù) 描述
服務(wù)器端套接字
s.bind() 綁定地址(host,port)到套接字, 在 AF_INET 下,以元組(host,port)的形式表示地址。
s.listen() 開(kāi)始 TCP 監(jiān)聽(tīng)。backlog 指定在拒絕連接之前,操作系統(tǒng)可以掛起的最大連接數(shù)量。該值至少為 1,大部分應(yīng)用程序設(shè)為 5 就可以了。
s.accept() 被動(dòng)接受 TCP 客戶(hù)端連接,(阻塞式)等待連接的到來(lái)
客戶(hù)端套接字
s.connect() 主動(dòng)初始化 TCP 服務(wù)器連接,。一般 address 的格式為元組(hostname,port),如果連接出錯(cuò),返回 socket.error 錯(cuò)誤。
s.connect_ex() connect() 函數(shù)的擴(kuò)展版本,出錯(cuò)時(shí)返回出錯(cuò)碼,而不是拋出異常
公共用途的套接字函數(shù)
s.recv() 接收 TCP 數(shù)據(jù),數(shù)據(jù)以字符串形式返回,bufsize指定要接收的最大數(shù)據(jù)量。flag 提供有關(guān)消息的其他信息,通??梢院雎?。
s.send() 發(fā)送 TCP 數(shù)據(jù),將 string 中的數(shù)據(jù)發(fā)送到連接的套接字。返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于 string 的字節(jié)大小。
s.sendall() 完整發(fā)送 TCP 數(shù)據(jù),完整發(fā)送 TCP 數(shù)據(jù)。將 string 中的數(shù)據(jù)發(fā)送到連接的套接字,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)。成功返回 None,失敗則拋出異常。
s.recvfrom() 接收 UDP 數(shù)據(jù),與 recv() 類(lèi)似,但返回值是(data,address)。其中 data 是包含接收數(shù)據(jù)的字符串,address 是發(fā)送數(shù)據(jù)的套接字地址。
s.sendto() 發(fā)送 UDP 數(shù)據(jù),將數(shù)據(jù)發(fā)送到套接字,address 是形式為(ipaddr,port)的元組,指定遠(yuǎn)程地址。返回值是發(fā)送的字節(jié)數(shù)。
s.close() 關(guān)閉套接字
s.getpeername() 返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一個(gè)元組(ipaddr,port)
s.setsockopt(level,optname,value) 設(shè)置給定套接字選項(xiàng)的值。
s.getsockopt(level,optname[.buflen]) 返回套接字選項(xiàng)的值。
s.settimeout(timeout) 設(shè)置套接字操作的超時(shí)期,timeout 是一個(gè)浮點(diǎn)數(shù),單位是秒。值為 None 表示沒(méi)有超時(shí)期。一般,超時(shí)期應(yīng)該在剛創(chuàng)建套接字時(shí)設(shè)置,因?yàn)樗鼈兛赡苡糜谶B接的操作(如 connect())
s.gettimeout() 返回當(dāng)前超時(shí)期的值,單位是秒,如果沒(méi)有設(shè)置超時(shí)期,則返回 None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag) 如果 flag 為 0,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)。非阻塞模式下,如果調(diào)用 recv() 沒(méi)有發(fā)現(xiàn)任何數(shù)據(jù),或 send() 調(diào)用無(wú)法立即發(fā)送數(shù)據(jù),那么將引起 socket.error 異常。
s.makefile() 創(chuàng)建一個(gè)與該套接字相關(guān)連的文件

簡(jiǎn)單實(shí)例

服務(wù)端

我們使用 socket 模塊的 socket 函數(shù)來(lái)創(chuàng)建一個(gè) socket 對(duì)象。socket 對(duì)象可以通過(guò)調(diào)用其他函數(shù)來(lái)設(shè)置一個(gè) socket 服務(wù)。

現(xiàn)在我們可以通過(guò)調(diào)用 bind(hostname, port) 函數(shù)來(lái)指定服務(wù)的 port(端口)。

接著,我們調(diào)用 socket 對(duì)象的 accept 方法。該方法等待客戶(hù)端的連接,并返回 connection 對(duì)象,表示已連接到客戶(hù)端。

完整代碼如下:

#!/usr/bin/python3
# 文件名:server.py

# 導(dǎo)入 socket、sys 模塊
import socket
import sys

# 創(chuàng)建 socket 對(duì)象
serversocket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM) 

# 獲取本地主機(jī)名
host = socket.gethostname()

port = 9999

# 綁定端口
serversocket.bind((host, port))

# 設(shè)置最大連接數(shù),超過(guò)后排隊(duì)
serversocket.listen(5)

while True:
    # 建立客戶(hù)端連接
    clientsocket,addr = serversocket.accept()      

    print("連接地址: %s" % str(addr))
    
    msg='歡迎訪問(wèn)W3Cschool教程!'+ "\r\n"
    clientsocket.send(msg.encode('utf-8'))
    clientsocket.close()

客戶(hù)端

接下來(lái)我們寫(xiě)一個(gè)簡(jiǎn)單的客戶(hù)端實(shí)例連接到以上創(chuàng)建的服務(wù)。端口號(hào)為 12345。

socket.connect(hosname, port ) 方法打開(kāi)一個(gè) TCP 連接到主機(jī)為 hostname 端口為 port 的服務(wù)商。連接后我們就可以從服務(wù)端后期數(shù)據(jù),記住,操作完成后需要關(guān)閉連接。

完整代碼如下:

#!/usr/bin/python3
# 文件名:client.py

# 導(dǎo)入 socket、sys 模塊
import socket
import sys

# 創(chuàng)建 socket 對(duì)象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 獲取本地主機(jī)名
host = socket.gethostname() 

# 設(shè)置端口好
port = 9999

# 連接服務(wù),指定主機(jī)和端口
s.connect((host, port))

# 接收小于 1024 字節(jié)的數(shù)據(jù)
msg = s.recv(1024)

s.close()

print (msg.decode('utf-8'))

現(xiàn)在我們打開(kāi)連個(gè)終端,第一個(gè)終端執(zhí)行 server.py 文件:

$ python3 server.py

第二個(gè)終端執(zhí)行 client.py 文件:

$ python3 client.py 
歡迎訪問(wèn)W3Cschool教程!

這是我們?cè)俅蜷_(kāi)第一個(gè)終端,就會(huì)看到有以下信息輸出:

連接地址: ('192.168.0.118', 33397)

Python Internet 模塊

以下列出了 Python 網(wǎng)絡(luò)編程的一些重要模塊:

協(xié)議 功能用處 端口號(hào) Python 模塊
HTTP 網(wǎng)頁(yè)訪問(wèn) 80 httplib, urllib, xmlrpclib
NNTP 閱讀和張貼新聞文章,俗稱(chēng)為"帖子" 119 nntplib
FTP 文件傳輸 20 ftplib, urllib
SMTP 發(fā)送郵件 25 smtplib
POP3 接收郵件 110 poplib
IMAP4 獲取郵件 143 imaplib
Telnet 命令行 23 telnetlib
Gopher 信息查找 70 gopherlib, urllib

更多內(nèi)容可以參閱官網(wǎng)的 Python Socket Library and Modules。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)