【Python大師之路】Socket網路程式設計基礎

by - 晚上11:04


        在Python中,要完成網路通訊,可以利用Socket模組來完成,Socket的使用方式與其他程式語言上的socket蠻像的,相信上手不難。
        在開始一次連線之前,要先創建一個socket變數,可以利用socket模組內的socket函式來完成。我們要先告訴socket函示我們要創建的連接類型是什麼,而python中支援的連線類型大概有以下幾種:

  • socket.AF_UNIX:本機通訊
  • socket.AF_INET:網路通訊
  • socket.AF_INET6:IPv6的網路通訊
  • socket.SOCK_STREAM:TCP協定
  • socket.SOCK_DGRAM:UDP協定
  • socket.SOCK_RAW:不使用任何協定解析(通常用在封包分析上)
  • socket.SOCK_SEQPACKET:建立一個可靠的連結(不常用,僅linux系統支援)
上面用螢光標記的是比較常用的連接類型。如果我們要創建一個TCP連接的socket,可以這樣寫:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
而UDP連接的socket可以這樣創建:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
這樣就能完成socket的創建了,而網路通信就會有客戶端和伺服端,這邊將一一介紹兩者會用到的函式。
這邊要注意,我們在發送數據時,只能發送字串,不能發送列表等帶有資料型別的變數。

伺服器端函數

以下的s假設為一個socket變數

  • s.bind(address):綁定在指定地址上,address的格式是一個tuple:(host, port),host是本機IP、port是要綁定的端口。
  • s.listen(backlog):等待連線,backlog是允許最大的連線數,像s.listen(3)就只允許3個人連進來,超過者拒絕連線。
  • s.accept():連接成功後,會回傳一個tuple:(conn, address),conn是新的socket,可以用來收發資料;address是連接客戶端的IP位址。

客戶端函數


  • s.connect(address):連結伺服器,address的格式是一個tuple:(hostport),host是伺服器端IP、port是伺服器端綁定的端口。如果連線失敗,會傳回socket.error。
  • s.connect_ex(address):功能跟connect(address)一樣,只是如果成功連線會回傳0,失敗會回傳error的數值。

都可以使用的函數



  • s.recv(bufsize[, flag]):接收TCP連接的資料,資料以字串形式回傳bufsize是要接收的最大資料量。flag提供其他訊息,但通常可以忽略。
  • s.send(string[, flag]):以TCP協定發送資料,會回傳要發送的資料量。
  • s.sendall(string[, flag]):嘗試一次完整發送整個string,失敗會拋出例外。

  • s.recvfrom(bufsize[, flag]):接收UDP資料,會回傳一個tuple:(data, address),data是資料,而address是發送端的IP。
  • s.sendto(string[, flag], address):發送UDP資料,address的格式是一個tuple:(ipaddrport),指定伺服器發送,和send一樣,會回傳要發送的量。

  • s.close():關閉socket。

  • s.getpeername():回傳socket另一端的地址及端口,型態通常是一個tuple:(ipaddr, port)。
  • s.getsockname():回傳socket自己的地址及端口,型態通常是一個tuple:(ipaddrport)。

  • s.setsockopt(level, optname, value):把soptname設置為value
  • s.getsockopt(level, optname[, buflen]):取得在s中,optname的值。

  • s.settimeout(timeout):設定判斷連線逾時的秒數,timeout的值是浮點數,單位為秒,若設定為None則永遠不會超時。
  • s.gettimeout():回傳超時設定,單位為秒,如果沒有設定就會回傳None。

  • s.fileno():返回s的文件描述
  • s.setblocking(flag):‎如果flag是0,則設置為非阻塞模式,否則設置為阻塞模式(預設值)。 非阻塞模式下,如果調用recv()沒有發現任何資料,或send()調用無法立即發送資料,那麼將拋出socket.error例外。‎
  • s.makefile():創建一個與s相關的文件
接下來給一組範例演示一下吧:

伺服端


import socket

HOST = '192.168.1.100'#設定要綁定的地址
PORT = 8001

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#創建socket
s.bind((HOST, PORT))#綁定
s.listen(5)#監聽

#進入無窮迴圈等代客戶端連線
while True:
    conn, addr = s.accept()
    print 'Connected by ', addr
    #連線成功後,不斷接收並印出資料,並回傳收到
    while True:
        data = conn.recv(1024)
        print data

        conn.send("server received you message.")

# conn.close()

客戶端


import socket

#伺服器資訊
HOST = '192.168.1.100'
PORT = 8001

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#創建socket
s.connect((HOST, PORT))

#不斷發送使用者輸入的訊息給伺服器
while True:
    msg = raw_input("Please input msg:")
    s.send(msg)#發送
    data = s.recv(1024)#接收伺服器訊息
    print data

    #s.close()

本篇教學就到這邊,如喜歡我們的文章記得到粉專案讚取得第一手的資訊喔!
程式碼下載:
客戶端:Github下載
服務端:Github下載

你可能會喜歡

0 意見