Python中非阻塞socket

来自socket的unblock(非阻塞)

前言

由于普通的server-socket一次只能处理一个client-socket.

因为socket在accept等待接收和recv等待数据数据时都会阻塞, 每次处理client只能应对一个socket.

unblock code

server

# server
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(False)   # 将socket设置为非阻塞. 在创建socket对象后就进行该操作.

server.bind((socket.gethostbyname(socket.gethostname()), 4444))
server.listen(5)

client_list = []

while True:
    try:
        connection, addr = server.accept()
        client_list.append((connection, addr))
        print("connected:{}".format(addr))

    # accept原本是阻塞的, 等待connect, 设置setblocking(False)后, accept不再阻塞,
    # 它会(不断的轮询)要求必须有connect来连接, 不然就引发BlockingIOError, 所以为了在没有connect时,
    # 我们捕捉这个异常并pass掉.
    except BlockingIOError:
        pass

    for client_socket, client_addr in client_list:
        try:
            client_recv = client_socket.recv(1024)
            if client_recv:
                print("receive:{}>>>{}".format(client_addr, client_recv.decode('utf-8')))
                client_socket.send(client_recv)

            else:
                client_socket.close()
                print("downline:{}".format(client_addr))
                client_list.remove((client_socket, client_addr))

        except (BlockingIOError, ConnectionResetError):
            pass

client

# client
import socket
import time

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((socket.gethostbyname(socket.gethostname()), 4444))

while True:
    cRequest = input("send: ")
    client.send(cRequest.encode())
    if cRequest == "quit":
        print("[+] Down line......")
        time.sleep(2)
        client.close()
        break

大致流程

非阻塞的socket和普通socket的区别主要是:
1.server.setblocking(False)
2.pass掉BlockingIOError.
其他部分就自定义编写, client不需要setblocking.

猜你喜欢

转载自blog.csdn.net/One_of_them/article/details/81633721