Python 標準類庫 - 因特網協議與支持之socketserver
標準類庫 - 因特網協議與支持之socketserver
by:授客 QQ:1033553122
socketserver 模塊,簡化網絡服務編寫任務。
創建服務的步驟
1 通過子類化BaseRequestHandler 類,創建一個請求處理程序,並且重寫handle()方法,該方法將處理接收到的請求
2 傳遞服務器地址和請求處理程序類參數,實例化server類(如TCPServer)
3 調用server對象的handle_request()、serve_forever()方法,處理單個、多個請求
實例
socketserver.TCPServer
服務端(單線程服務器)
#!/usr/bin/env python 3.4.0
#-*- encoding:utf-8 -*-
__author__ = ‘shouke‘
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
供server使用的RequestHandler類.
每個客戶端連接連接到服務器時都會被初始化一次,並且必須重寫handle()方法以便同客戶端交流。
"""
def handle(self):
while True:
# self.request即為與客戶端連接的TCP socker
self.data = self.request.recv(1024).decode(‘utf-8‘).strip()
print(‘receive data from client[host:%s port:%s]:%s‘ % (self.client_address[0], self.client_address[1], self.data))
if self.data == ‘bye‘:
self.request.sendall(bytes(‘bye‘, encoding=‘utf-8‘))
self.request.close()
break
else:
self.request.sendall(self.data.upper().encode(‘utf-8‘))
if __name__ == ‘__main__‘:
# 創建TCPSocket服務器,綁定到10.118.52.26地址上,端口8000
server = socketserver.TCPServer((‘10.118.52.26‘, 8000), MyTCPHandler)
# 激活服務器,讓服務器一直運行,直到按Ctrl+C
server.serve_forever()
客戶端
#!/usr/bin/env python 3.4.0
#-*- encoding:utf-8 -*-
__author__ = ‘shouke‘
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
供server使用的RequestHandler類.
每個客戶端連接連接到服務器時都會被初始化一次,並且必須重寫handle()方法以便同客戶端交流。
"""
def handle(self):
while True:
# self.request即為與客戶端連接的TCP socker
self.data = self.request.recv(1024).decode(‘utf-8‘).strip()
print(‘receive data from client[host:%s port:%s]:%s‘ % (self.client_address[0], self.client_address[1], self.data))
if self.data == ‘bye‘:
self.request.sendall(bytes(‘bye‘, encoding=‘utf-8‘))
self.request.close()
break
else:
self.request.sendall(self.data.upper().encode(‘utf-8‘))
if __name__ == ‘__main__‘:
# 創建TCPSocket服務器,綁定到10.118.52.26地址上,端口8000
server = socketserver.TCPServer((‘10.118.52.26‘, 8000), MyTCPHandler)
# 激活服務器,讓服務器一直運行,直到按Ctrl+C
server.serve_forever()
運行結果
函數說明:
BaseServer.serve_forever(poll_interval=0.5)
處理shudown請求除外的請求。
有關socket說明
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
使用給定的地址家族,socket 類型,協議號創建一個新的socket。
family:默認為AF_INET,其它可選值有AF_INET6, AF_UNIX, AF_CAN or AF_RDS
type:默認為SOCK_STREAM,其它可選值有 SOCK_DGRAM, SOCK_RAW ,或者其它SOCK_XXX常量
protocol:通常為0或者忽略,當family為AF_CAN時,為CAN_RAW、CAN_BCM
Socket 對象
socket.close()
標記socket為closed
close()釋放與連接關聯的資源,但不一定立即關閉連接。如果要及時關閉連接,請在調用close()之前調用shutdown()。
socket.connect(address)
連接給定地址的遠程socket
socket.recv(bufsize[, flags])
從socket接收數據。返回值即為接收的數據。
buffsize:每次接收的最大數據量。.
flags默認為0
註意:為了同硬件和網絡設備最佳匹配,buffsize應該為一個相對小的2次冪,比如4096
socket.sendall(bytes[, flags])
發送字節數據到socket。不同於send方法,該方法會持續發送bytes參數給定的數據,直到所有數據被發送、錯誤發生。如果發送成功,則返回None,否則拋出異常。沒有方法判斷到底成功發送了多少數據
socket.send(bytes[, flags])
發送字節數據到socket。返回發送字節數,如果只傳輸了部分數據,程序會嘗試發送剩余數據。
更多資料參考官方文檔,socket模塊
服務端(多線程服務器)
#!/usr/bin/env python 3.4.0
#-*- encoding:utf-8 -*-
__author__ = ‘shouke‘
import socket
import time
if __name__ == ‘__main__‘:
if_sock_connected = False
try:
# 創建一個socket (SOCK_STREAM 表示為TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接到服務器
sock.connect((‘10.118.52.26‘, 8000))
# 發送數據
if_sock_connected = True
i = 0
while i < 100:
if i == 6:
sock.sendall(bytes(‘bye\n‘, "utf-8"))
else:
sock.sendall(bytes(‘hello world with tcp\n‘, "utf-8"))
print("sent data to server:{}".format(bytes(‘hello world with tcp\n‘, "utf-8")))
# 從服務器接收數據
received = str(sock.recv(1024), "utf-8")
print(‘receive data from server:%s‘ % received)
if received == ‘bye‘:
break
time.sleep(1)
i += 1
except Exception as e:
print(‘程序運行出錯:%s‘ % e)
finally:
if if_sock_connected:
sock.close()
運行結果
更多資料,煩參考官方文檔,socketserver模塊。
Python 標準類庫 - 因特網協議與支持之socketserver