程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 基礎Python的socket編本入門介紹

基礎Python的socket編本入門介紹

編輯:更多關於編程

       基礎Python的socket編本入門介紹

             這篇文章主要介紹了最基礎的Python的socket編程入門教程,包括最基本的發送和接受信息等內容,需要的朋友可以參考下

      本文介紹使用Python進行Socket網絡編程,假設讀者已經具備了基本的網絡編程知識和Python的基本語法知識,本文中的代碼如果沒有說明則都是運行在Python 3.4下。

      Python的socket功能封裝在socket庫中,要使用socket,記得先import socket,socket庫的詳細介紹參見官方文檔。

      創建Socket

      首先創建一個socket,使用socket庫中得socket函數創建。

      ?

    1 import socket

      ?

    1 2 # create an INET, STREAM socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      例子中創建了一個TCP socket,socket.socket函數的前兩個參數的默認值是socket.AF_INET和socket.SOCK_STREAM,創建TCP socket時可以直接寫成socket.socket()。

      連接服務器

      使用socket的connect函數連接到服務器,以下幾種參數都是合法的。

      ?

    1 2 3 s.connect(('localhost', 8000)) s.connect(('127.0.0.1', 8000)) s.connect(('www.baidu.com', 80))

      發送數據

      發送數據有兩個方法send和sendall,send不能保證所有的數據都發送完了,它會返回已發送數據的長度,程序要循環發送數據直到所有數據都已發送完畢。

      ?

    1 2 3 4 5 6 7 8 def mysend(s, msg): total_len = len(msg) total_sent = 0 while total_sent < total_len: sent = s.send(msg[total_sent:]) if sent == 0: raise RuntimeError("socket connection broken") total_sent += sent

      sendall能夠保證所有的數據都已發送完畢,除非發送過程中出現了錯誤,它實際上也是循環發送數據直到所有數據發送完成。

      這裡還要講一個需要特別注意的地方,從一個例子開始吧:

      ?

    1 2 3 4 import socket s = socket.socket() s.connect(('www.baidu.com', 80)) s.sendall('test')

      都是上面講過的東西,沒什麼特別的,分別在Python 2和Python 3中執行以上的代碼,結果是:

      ?

    1 2 3 4 5 # Python 2.7 >>> import socket >>> s = socket.socket() >>> s.connect(('www.baidu.com', 80)) >>> s.sendall('test')

      Python 2中執行成功。

      ?

    1 2 3 4 5 6 7 8 # Python 3.4 >>> import socket >>> s = socket.socket() >>> s.connect(('www.baidu.com', 80)) >>> s.sendall('test') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' does not support the buffer interface

      Python 3中卻發生了異常。

      同樣的代碼換個環境卻不能執行了,我沒有寫錯呀,怒砸電腦。好吧,你確實沒寫錯,是環境變了,導致這個結果的變化請移步官方的說明。

      接收數據

      使用recv函數接收數據:

      ?

    1 data = s.recv(4096)

      在Python 3中返回的是bytes對象,在Python 2中返回的是string。注意函數返回的數據長度是小於或者等於參數指定的長度的,要接收到指定長度的數據,需要循環接收數據。

      ?

    1 2 3 4 5 6 7 8 9 10 def myreceive(s, msglen): chunks = [] bytes_recd = 0 while bytes_recd < msglen: chunk = s.recv(min(msglen - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") chunks.append(chunk) bytes_recd = bytes_recd + len(chunk) return b''.join(chunks)

      關閉連接

      當連接不再需要時可以使用close關閉socket連接,關閉後的連接不能再進行任何操作。當一個socket被回收時會自動關閉,但是不要依賴這種機制,不需要socket時就主動的close。

      服務端

      服務端程序執行的步驟:

      1. 創建服務端socket

      1. 將服務端socket綁定到指定的地址和端口

      1. 監聽連接

      1. 接受客戶端連接

      1. 處理客戶端的數據

      1. 關閉客戶端連接

      一個簡單的echo server示例:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import socket   HOST = '' PORT = 10022   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(10) conn, addr = s.accept() while True: data = conn.recv(1024) if not data: break conn.sendall(data) conn.close()

      客戶端程序:

      ?

    1 2 3 4 5 6 7 8 9 10 11 import socket   HOST = 'localhost' PORT = 10022   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall(b'hello socket') data = s.recv(1024) print('Received', repr(data)) s.close()

      錯誤處理

      socket處理過程中發生錯誤會拋出異常,socket相關的異常有:

      - socket.error

      - socket.herror

      - socket.gaierror

      - socket.timeout

      ?

    1 2 3 4 5 6 7 8 9 10 11 import socket   HOST = None PORT = 10022   try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(10) except: socket.error as msg: print(msg)
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved