python3-socketserver


socketserver模組

  模組socketserver是標準庫提供的伺服器框架基礎.

這個框架包括了BaseHTTPServer , SimpleHTTPServer , CGIHTTPServer , SimpleXMLRPCServer , DocXMLRPCServer

等伺服器,他們在基本伺服器的基礎上添加了各種功能。

  socketserver包含了4個基本的伺服器

                        1.TCPServer(支援TCP套接字流)

                        2.UDPServer(支援UDP數據報套接字)

                        3.UnixStreamServer和UnixDatagramServer

編寫服務端底層流程:

   伺服器接受客戶端連接請求——》實例話一個請求處理程式——》根據伺服器類和請求處理程式類,調用處理方法。

例如:

   基本請求程式類(BaseRequestHandler)調用方法 handle 。此方法通過屬性 self.request 來訪問客戶端套接字、

StreamRequestHandler類(處理流),通過屬性self.rfile(用於讀取)和self.wfile(用於寫入),進行與客戶端通訊

基於tcp的socketserver,自定義類中:

      conn,client_addr=socket(AF_INET,SOCK_STREAM)

  1. self.server即套接字對象  <socketserver.ThreadingTCPServer object at 0x000001DA1221FB00>
  2. self.request即一個鏈接  self.request = conn ; 如: <socket.socket fd=472, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 59405)>
  3. self.client_address即客戶端地址 self.client_address = client_addr  ; ('127.0.0.1', 59405)                                                                            

基於udp的socketserver,自定義類中:

  1. self.request是一個元組(第一個元素是客戶端發來的數據,第二部分是服務端的udp套接字對象)                                      如:(b'adsf', <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>)
  2. self.client_address即客戶端地址 ('127.0.0.1', 50323)

基於TCP鏈接的簡單並發程式

服務端:

import socketserver      # 自定義類來實現通訊循環  class MyTCPHandler(socketserver.BaseRequestHandler):      # 必須寫入handle方法,建立鏈接時會自動執行handle方法      def handle(self):          while True:              try:                  data = self.request.recv(1024)                  if not data: break                  print('->client:', data)                  self.request.send(data.upper())              except ConnectionResetError:                  break          self.request.close()      if __name__ == '__main__':      server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyTCPHandler)      server.serve_forever()  # 鏈接循環

客戶端1/2/3/4……

import socket    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  client.connect(('127.0.0.1',8080))    while True:      client.send('hello'.encode('utf-8'))      data = client.recv(1024)      print(data)

基於UDP無鏈接的簡單並發程式

服務端:

import socketserver      # 自定義類來實現通訊循環  class MyUDPHander(socketserver.BaseRequestHandler):      def handle(self):          data,sock = self.request          sock.sendto(data.upper(),self.client_address)    if __name__ == '__main__':      server = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyUDPHander)      server.serve_forever()  # 鏈接循環

客戶端1/2/3/4……:

from socket import *    client = socket(AF_INET,SOCK_DGRAM)    while True:      client.sendto(b'hello',('127.0.0.1',8080))      data,server_add = client.recvfrom(1024)      print(data)

錯誤筆記:

ConnectionAbortedError: [WinError 10053] 你的主機中的軟體中止了一個已建立的連接。

– 服務端程式碼錯誤

– 解決方法:自定義handler類內必須寫入handle方法

ConnectionRefusedError: [WinError 10061] 由於目標電腦積極拒絕,無法連接。

– 解決方法:kill相關進程重新啟動