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

  • 相关阅读:
    echo -e的用法
    nc ip 22
    /pentest/backdoors/3proxy
    /usr/local/sbin/arpspoof
    tcpick
    nginx服务报403错误的解决方法
    linux上部署thinkphp5提示500
    修改文件夹的所有者为www
    Host xxx is not allowed to connect to this MariaDb server
    解决Linux 下 root用户删除文件提示:Operation not permitted
  • 原文地址:https://www.cnblogs.com/aizhinong/p/11519420.html
Copyright © 2020-2023  润新知