socket中的listen與accept


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()
server端
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()
client端1
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()
client端2
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()
client端3

  測試2,啟動用戶端1,2后,關閉用戶端1或2,再啟動用戶端3,用戶端3不會報錯

總結:

listen的socket對象比喻為火車站

accept的socket對象理解需要接待的旅客

如果要接到旅客,首先要到火車站等待(即listen監聽的socket對象)

旅客是否到達,需要在入口處檢查有沒有等待的旅客(即accept在檢查是否有新連接產生的socket對象),

如果超過火車站限制人數(listen限制隊列數量),該發送請求的用戶端報錯,只能等待正在連接的用戶端斷開才能成功進入隊列等待


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM