2022年1月12日 星期三

Python socket基本使用

Python socket基本使用




三次握手協定的過程:

  1. 客戶端(通過執行connect函式)向伺服器端傳送一個SYN包,請求一個主動打開。該包攜帶客戶端為這個連接請求而設定的亂數A作為訊息序列號。
  2. 伺服器端收到一個合法的SYN包後,把該包放入SYN佇列中;回送一個SYN/ACK。ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序號B
  3. 客戶端收到SYN/ACK包後,傳送一個ACK包,該包的序號被設定為A+1,而ACK的確認碼則為B+1。然後客戶端的connect函式成功返回。當伺服器端收到這個ACK包的時候,把請求影格從SYN佇列中移出,放至ACCEPT佇列中;這時accept函式如果處於阻塞狀態,可以被喚醒,從ACCEPT佇列中取出ACK包,重新建立一個新的用於雙向通信的sockfd,並返回。

源自https://www.itread01.com/content/1545266524.html

1)socket函式

  功能:使用給定的地址族、套接字型別、協議編號(預設為0)來建立套接字。

  格式:socket.socket([family[, type[, proto]]])

  引數:

    family : AF_INET (預設ipv4),AF_INET6(ipv6) , AF_UNIX(Unix系統程序間通訊).

    type : SOCK_STREAM (TCP), SOCK_DGRAM(UDP) .

    protocol : 一般為0或者預設

  備註:如果socket建立失敗會丟擲一個socket.error異常

2)伺服器端函式

   a)bind函式

  格式:s.bind(address)

  功能:將地址address繫結到套接字, 地址以元組(host,port)的形式表示。

  引數:

    address為元組(host,port)

    host: ip地址, 為一個字串

    post: 自定義主機號, 為整型

b)listen函式

  格式:s.listen(backlog)

  功能:使伺服器的這個埠和IP處於監聽狀態,等待網路中某一客戶機的連線請求。如果客戶端有連線請求,埠就會接受這個連線。

  引數:backlog : 作業系統可以掛起的最大連線數量。該值至少為1,大部分應用程式設為5就可以了

c)accept函式

  格式:s.accept()

  功能:接受遠端計算機的連線請求,建立起與客戶機之間的通訊連線。伺服器處於監聽狀態時,如果某時刻獲得客戶機的連線請求,此時並不是立即處理這個請求,而是將這個請求放在等待佇列中,當系統空閒時再處理客戶機的連線請求。

  返回值:返回一個數組(conn,address),其中conn是新的套接字物件,可以用來接收和傳送資料。address是連線客戶端的地址

3)客戶端函式

  a)connect函式

  格式:s.connect(address)

  功能:用來請求連線遠端伺服器

  引數:address為遠端伺服器地址, 格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤

  b)connect_ex函式

  格式:s.connect_ex(address)

  備註:connect()函式的擴充套件版本,出錯時返回出錯碼,而不是丟擲異常

4)通用函式

  a)recv函式

  格式:s.recv(bufsize[,flag])

  功能:接收遠端主機傳來的資料

  引數:

    bufsize : 指定要接收的資料大小

    flag : 提供有關訊息的其他資訊,通常可以忽略

  返回值:返回值為資料以字串形式</code>

  b)send函式

  格式:s.send(string[,flag])

  功能:傳送資料給指定的遠端主機

  引數:

    string : 要傳送的字串資料

    flag : 提供有關訊息的其他資訊,通常可以忽略

  返回值:返回值是要傳送的位元組數量,該數量可能小於string的位元組大小。

c)sendall函式

  格式:s.sendall(string[,flag])

  功能:內部呼叫了send函式,完整發送TCP資料。將string中的資料傳送到連線的套接字,但在返回之前會嘗試傳送所有資料。

  引數:同send函式

  返回值 : 成功返回None,失敗則丟擲異常。

d)close函式

  格式:s.close()

  功能:關閉套接字

e)recvfrom函式

  格式:s.recvfrom(bufsize[.flag])

  功能:與recv()類似,區別是返回值不同

  返回值:返回一個數組(data,address),其中data是包含接收資料的字串,address是傳送資料的套接字地址。

f)sendto函式

  格式:s.sendto(string[,flag],address)

  功能:將資料傳送到套接字

  引數:

    string : 要傳送的字串資料

    flag : 提供有關訊息的其他資訊,通常可以忽略

    address是形式為(ipaddr,port)的元組,指定遠端地址

  返回值:返回值是要傳送的位元組數量

  備註:該函式主要用於UDP協議。

g)settimeout函式

  格式:s.settimeout(timeout)

  功能:設定套接字操作的超時期

  引數:timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛建立套接字時設定,因為它們可能用於連線的操作(如 client 連線最多等待5s )

h)getpeername函式

  格式:s.getpeername()

  功能:獲取連線套接字的遠端地址

  返回值:返回值通常是元組(ipaddr,port)。

i)getsockname函式

  格式:s.getsockname()

  功能:獲取套接字自己的地址

  返回值:通常是一個元組(ipaddr,port)

  socket中常用的函式就上面這些了。先用上面這些函式嘗試TCP協議下的socket通訊。


import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8088))
mes_to_server = '你好,Linux公社www.linuxidc.com伺服器!'.encode('utf-8')#傳送的資料必須是byte型別
sk.send(mes_to_server)
mes_from_server = sk.recv(1024).decode('utf-8')
print(mes_from_server)
sk.close() 



import socket
sk = socket.socket()
sk.bind(('127.0.0.1' ,8088))
sk.listen(5)
print('正在等待Linux公社客戶端連線……')
conn , addr = sk.accept()
print('Linux公社客戶端已連線到伺服器……')
mes_from_client = conn.recv(1024).decode('utf-8')
print(mes_from_client)
mes_to_server = '你好,Linux公社www.linuxidc.com客戶端,已收到您的資訊!'.encode('utf-8')#傳送的資料必須是byte型別
conn.send(mes_to_server)
conn.close()
sk.close()


沒有留言:

張貼留言

WOKWI LED + MQTT Node-Red SQLite

WOKWI LED + MQTT Node-Red SQLite const char *mqtt_broker = "broker.mqtt-dashboard.com" ; const char *topic1 = "alex9ufo/e...