python套接字基本使用

gxyz發表於2016-09-26

socket

socket通常也稱作"套接字",用於描述IP地址和埠,應用程式通常通過"套接字"向網路發出請求或者應答網路請求,可以認為是一種計算機網路的資料結構,介面。它是網路程式設計的基礎

套接字最早起源於Unix系統,一開始使用與一臺電腦之間的程式間通訊,目前套接字分為兩種,基於檔案型和基於網路型。其中一臺主機的程式間是通過基於檔案的套接字進行通訊(AF_UNIX或者AF_LOCAL)。而還有一種基於網路的,可用於不同主機之間的通訊(AF_INET和AP_INET6),AF_INET是用於IPV4,而AF_INET6是用於IPV6。

套接字還分為面向連線的和無連線的:

  1. 第一種是指TCP型別套接字,在通訊前需要建立連線,這種連線是較為可靠的,使用的套接字型別是SOCK_STREAM,TCP傳輸控制協議,經常和IP協議一起使用,稱為TCP/IP協議
  2. 第二種主要指UDP型別的套接字,無需連線就可以進行通訊,所有速度較快,但是可靠性不高。而且資料是整個傳送,不會分成小塊。使用的套接字型別是SOCK_DGRAM,UDP協議通常也與IP協議一起使用

python中的socket模組

使用套接字的基本步驟:

  • 建立套接字
socket(socket_family, socket_type, protocol)
#socket_family 就是指套接字家族可以是AF_VNIX或AF_INET
#socket_type 就是指套接字型別,即SOCK_STREAM或SOCK_DGRAM
#protocol 是協議,預設為0,一般不填
  • 建立TCP/IP或者UDP/IP套接字
    1. 建立TCP/IP套接字
    import socket
    tcp = socket.socket(AF_INET, SOCK_STREAM)
    1. 建立UDP/IP套接字
    import socket
    ucp = socket.socket(AF_INET, SOCK_DGRAM)
  • 套接字的常用函式
函式名 描述
伺服器套接字
bind((hostname, port)) 繫結地址(注意這裡是元祖)到套接字
listen() 開啟TCP監聽
accept() 被動接受客戶端的連線(阻塞)
客戶端套接字
connect((hostname, port)) 初始化TCP伺服器連線
connect_ex() connect()的擴充套件版本,出錯時返回錯誤碼,而不是異常
公用的套接字
recv() 接收TCP的資料
send() 傳送TCP資料
sendall() 傳送完整的TCP資料
recvfrom() 接收UDP資料
sendto() 發生UDP資料,因為沒有連線,所以這裡要指定傳送的目標
getpeername() 連線到當前套接字的遠端地址
getsockname() 當前socket地址
getsockopt() 獲得套接字的引數
setsockopt() 設定套接字的引數
close() 關閉套接字
面向模組的套接字函式
setblocking() 設定套接字是否是阻塞模式
settimeout() 設定阻塞套接字操作的超時時間
gettimeout() 得到阻塞套接字操作的超時時間
面向檔案的套接字函式
fileno() 套接字的檔案描述符
makefile() 建立一個與套接字關聯的檔案物件

建立一個TCP伺服器和客戶端

建立TCP伺服器的基本步驟

  1. 建立套接字並繫結地址
  2. 開始監聽連線
  3. 接收連結併傳送資料
  4. 關閉套接字

程式碼如下:


import socket

HOST = ''   #空字串標示127.0.0.1
PORT = 3214

sk = socket.socket() # 預設使用IPV4和TCP

sk.bind((HOST,PORT))

sk.listen(5)

cli, addr = sk.accept() # 等待連線(阻塞式),在連線到來之前會阻塞在這裡

print "Client Addr:", addr

while True:
    data = cli.recv(1024)
    if not data:
        break
    print "Recieve Data:", data.decode('utf-8')
    cli.send(data)

cli.close()

建立TCP客戶端的基本步驟

  1. 建立套接字,連線伺服器
  2. 收發資料
  3. 關閉套接字
import socket

HOST = '127.0.0.1'
PORT = 3214

sk = socket.socket()

try:
    sk.connect((HOST, PORT))
    data = "hello"
    while data:
        sk.sendall(data)
        data = sk.recv(1024)
        print "Recv data:", data
        data = raw_input('Please input message\n')
except socket.error as err:
    print err
finally:
    sk.close()

這裡的客戶端僅僅可以用來傳送訊息給服務端,而服務端會接收訊息然後重新傳送回客戶端

建立UDP伺服器和客戶端

建立UDP服務端的基本步驟

  1. 建立套接字並繫結地址
  2. 開始監聽連線
  3. 收發資料
  4. 關閉套接字
import socket

HOST = ''
PORT = 3214

sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sk.bind((HOST, PORT))

data = True

while data:
    data, addr = sk.recvfrom(1024)
    if data == b'bye':
        break
    print "Recieve Data:", data.decode('utf-8')
    sk.sendto(data, addr)

sk.close()

建立UDP客戶端的基本步驟

  1. 建立套接字
  2. 收發資料
  3. 關閉套接字
import socket

HOST = '127.0.0.1'
PORT = 3214

sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

data = 'hello'

while data:
    sk.sendto(data, (HOST, PORT))
    if data == "bye":
        break
    data, addr = sk.recvfrom(1024)
    print "Recv Data:", data
    data = raw_input('Please message:\n')

sk.close()

# tcpclient與udpclient區別
# 建立socket時的區別
# tcp需要連結服務端
# 收發資料方法不同

這裡與TCP的區別就是不用建立連線,客戶端只是收發訊息,並不會與伺服器建立連線

相關文章