listen:
建立監聽,能否建立需要accept函數去進行檢查
def listen(self, backlog: int) #backlog指定最多允許多少個客戶連接到服務器。它的值至少為1。收到連接請求后,這些請求需要排隊,如果隊列滿,就拒絕請求。
注意:backlog應該理解為阻塞隊列的長度,總共與服務器連接的客戶端一共有 backlog + 1 個。阻塞隊列FIFO,當連接客戶端結束后阻塞隊列里的第一個客服端與服務器連接成功。
accept:
def accept(self): """accept() ->(套接字對象,地址信息) 等待傳入連接。返回一個新的套接字 表示連接和客戶端的地址。 對於IP套接字,地址信息是一對(hostaddr, port)。 """
accept()接受一個客戶端的連接請求,並返回一個新的套接字,不同於server端的socket()返回用於監聽和接受客戶端的連接請求的套接字;與客戶端通信是通過這個新的套接字上發送和接收數據來完成的。每個連接進來的客戶端,都會通過accept函數返回一個不同的客戶端的socket對象和屬於客戶端的套接字
測試:假設服務端永久開啟,listen設置有允許有1個用戶端在等待,同時啟動三個用戶端:
啟動第1個用戶端,程序正常運行
啟動第2個用戶端,程序正常運行,但是在listen當中排隊等待第一個用戶端的斷開
啟動第3個用戶端,次用戶端報錯:onnectionRefusedError: [WinError 10061] 由於目標計算機積極拒絕,無法連接。

import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(1) while True: conn,addr = sk.accept() while True: ret = conn.recv(1024).decode('utf-8') print(ret) if ret == 'bye': conn.send(b'bye') break msg = input('>>') conn.send(msg.encode('utf-8')) conn.close() sk.close()

import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: info = input('>>') sk.send(info.encode('utf-8')) ret = sk.recv(1024).decode('utf-8') print(ret) if ret == 'bye': sk.send(b'bye') break sk.close()

import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: info = input('>>') sk.send(info.encode('utf-8')) ret = sk.recv(1024).decode('utf-8') print(ret) if ret == 'bye': sk.send(b'bye') break sk.close()

import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: info = input('>>') sk.send(info.encode('utf-8')) ret = sk.recv(1024).decode('utf-8') print(ret) if ret == 'bye': sk.send(b'bye') break sk.close()
測試2,啟動用戶端1,2后,關閉用戶端1或2,再啟動用戶端3,用戶端3不會報錯
總結:
listen的socket對象比喻為火車站
accept的socket對象理解需要接待的旅客
如果要接到旅客,首先要到火車站等待(即listen監聽的socket對象)
旅客是否到達,需要在入口處檢查有沒有等待的旅客(即accept在檢查是否有新連接產生的socket對象),
如果超過火車站限制人數(listen限制隊列數量),該發送請求的用戶端報錯,只能等待正在連接的用戶端斷開才能成功進入隊列等待