利用python實現TCP和UDP服務器


  利用python的socket模塊可以實現基本的網絡編程,並且只限於一對一的連接。當然,也可以在其基礎上實現一個網絡服務器,但由於太底層這種做法不被推薦。其實如果要實現一個網絡服務器很簡單,調用python的內置模塊socketserver就夠了。

server類

  socketserver模塊下面有四種套接字server類:TCPserverUDPServerUnixStreamServerUnixDatagramServer。前兩種分別為使用TCP和UDP協議的server類,后兩種用法和前面一樣但只限於unix類系統。它們的參數都一樣,如下:

TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
  • 參數server_address: IP地址和端口,為一個元組如: ("127.0.0.1", 8000)
  • 參數RequestHandlerClass: 一個自定義的handle類,主要負責實現連接到來時所要執行的操作。后面會介紹怎么自定義。
  • 參數bind_and_activate: 默認為True。如果設置為False,代表你得手動操作底層的socket,這樣會更加靈活。

前面的四種類都繼承自一個BaseServer類,實現了基本方法和屬性:

  • fileno(): 返回一個服務器正綁定的socket文件描述符。
  • handle_requeset(): 處理一個請求。依次執行 get_request(), verify_request(), 和 process_request() 方法。用戶自定義的handleclass下的handle方法拋出異常,服務器的handle_error()會被調用。
  • server_forever(poll_interval=0.5): 進入一個循環, 一直接收並處理請求直到一個顯示的 shutdown() 請求到來。默認每隔0.5秒輪詢(pull)一次。
  • shutdown(): 告訴server_forever()得到的循環結束循環。
  • server_address(): 返回正在監聽的IP和端口,如:("127.0.0.1", 80)
  • socket: 正使用的socket對象
  • socket_type: socket類型,通常為:socket.SOCK_STREAM和socket.SOCK_DGRAM
  • timeout: 超時時間。

請求處理類

  通常需要繼承BaseRequestHandler,並重寫hanle()方法。當一個網絡請求被創建時,一個新的實例就會被創建。

 class socketserver.BaseRequestHandler

  方法如下:

  • setup(): 在handle()被調用前被執行,一般用於一些初始化操作。默認不執行任何操作。
  • handle(): 當一個請求到來后,用戶所要執行操作,這個方法應該被重寫,操作self.request。
  • finish(): handle之后調用的函數,用於執行一個清理工作。

server代碼如下:

 1 import socketserver
 2 
 3 class echorequestserver(socketserver.BaseRequestHandler):
 4     def handle(self):
 5         print('服務端啟動...')
 6         conn = self.request
 7         print('獲得連接:', self.client_address)
 8         while True:
 9             client_data = conn.recv(1024)
10             if not client_data:
11                 print('斷開連接')
12                 break
13             print(client_data.decode('utf-8'))
14             print('開始發送...')
15             conn.sendall(client_data)
16             
17 if __name__ == '__main__':
18     server =socketserver.TCPServer(("127.0.0.1", 8000),echorequestserver)  # 使用處理單連接的TCPServer
19     server.serve_forever()

客戶端代碼如下:

 1 import socket,time
 2 
 3 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 4 s.connect(('127.0.0.1',8000))
 5 
 6 while True:
 7     st = input('input command: ')
 8     if not st:break
 9     s.send(st.encode('utf-8'))
10     
11     echo_back = s.recv(1024)
12     print(echo_back.decode('utf-8'))
13  
14 s.close()

 

  當然,以上例子是用於單線程的情況。如果想同時接收多個連接,可以換成ThreadingTCPServer,用法和上面完全一樣。不過這種情況下,建議使用線程池以避免突然面臨多個連接同時到來的情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM