天天看點

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 socket

import time

if __name__ == '__main__':

    if_sock_connected = False

    try:

        # Create a socket (SOCK_STREAM means a TCP socket)

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Connect to server and send data

        sock.connect(('10.118.52.26', 8000))

        if_sock_connected = True # 标記socket是否已連接配接

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

            # Receive data from the server

            received = str(sock.recv(1024), "utf-8")

            logger.info('receive data from server:%s' % received)

            if received == 'bye':

                break

            time.sleep(5)

            i += 1

    except Exception as e:

        logger.error('程式運作出錯:%s' % e)

    finally:

        if if_sock_connected:

            sock.close()

運作結果      
Python 标準類庫 - 網際網路協定與支援之socketserver

函數說明:

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子產品

服務端(多線程伺服器)

import threading

import socketserver

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

    def handle(self):

        while True:

            # self.request即為與用戶端連接配接的TCP socker

            self.data = self.request.recv(1024).decode('utf-8').strip()

            cur_thread = threading.current_thread()

            print('%s receive data from client[host:%s port:%s]:%s' % (cur_thread.name, 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()

                self.request.sendall((cur_thread.name + ' ' + self.data.upper()).encode('utf-8'))

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):

    pass

def client(ip, port, message):

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:

        sock.connect((ip, port))

        sock.sendall(bytes(message, 'ascii'))

        response = str(sock.recv(1024), 'ascii')

        print("Received: {}".format(response))

if __name__ == "__main__":

    # 如果設定端口為0,則表示任意未被占用端口

    HOST, PORT = "localhost", 9000

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)

    ip, port = server.server_address

    # 開啟該server的一個線程,該線程會為每個請求開啟更多的線程

    server_thread = threading.Thread(target=server.serve_forever)

    # server退出時,終止線程

    #server_thread.setDaemon(True)

    server_thread.start()

    print("Server loop running in thread:", server_thread.name)

    # server.shutdown()

    # server.server_close()

用戶端

    try:

        # 建立一個socket (SOCK_STREAM 表示為TCP socket)

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 連接配接到伺服器

        sock.connect(('localhost', 9000))

        # 發送資料

        if_sock_connected = True

                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)

            time.sleep(1)

        print('程式運作出錯:%s' % e)

運作結果

Python 标準類庫 - 網際網路協定與支援之socketserver
Python 标準類庫 - 網際網路協定與支援之socketserver

更多資料,煩參考官方文檔,socketserver子產品。

作者:授客

QQ:1033553122

全國軟體測試QQ交流群:7156436

Git位址:https://gitee.com/ishouke

友情提示:限于時間倉促,文中可能存在錯誤,歡迎指正、評論!

作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額随意,您的支援将是我繼續創作的源動力,打賞後如有任何疑問,請聯系我!!!

           微信打賞                       

支付寶打賞                  全國軟體測試交流QQ群  

Python 标準類庫 - 網際網路協定與支援之socketserver
Python 标準類庫 - 網際網路協定與支援之socketserver
Python 标準類庫 - 網際網路協定與支援之socketserver