socket中的listen与accept

谁都会走 提交于 2019-11-29 14:18:51

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限制队列数量),该发送请求的用户端报错,只能等待正在连接的用户端断开才能成功进入队列等待

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!