这轮处理了哪几条

👁️ 2 人浏览 💬 0 人评论 ❤️ 添加收藏

同样第 0、2 条有数据,serve_ready 交回处理过的下标是什么?

贯穿全条的内存版 TCP(判题机不联网;接口和真 socket 一样,真机上换成 socket.socket() 就是真的):net = Net()lis = listen(net, 端口) 开监听;cli = connect(net, 端口) 客户端连上(交回客户端这头,服务端那头进 accept 队列);srv = lis.accept() 领一条连接;sendall 把字节追加进对面收缓冲,recv(n) 从自己收缓冲取最多 n 字节(拿到多少算多少,recv 交回 b"" 表示对面关了)。

多客户端(单线程轮询):ready(srvs) 交回收缓冲有数据的连接下标;serve_ready(srvs) 给每条有数据的各回一段(echo)、交回处理过的下标。

import collections


class Net:
    def __init__(self):
        self.listeners = {}


class Endpoint:
    def __init__(self, name):
        self.name = name
        self.rbuf = b""
        self.peer = None
        self.peer_closed = False
        self.closed = False

    def send(self, data):
        if self.closed or self.peer is None:
            raise BrokenPipeError("连接已关")
        self.peer.rbuf += bytes(data)
        return len(data)

    def sendall(self, data):
        self.send(data)

    def recv(self, bufsize):
        if self.rbuf:
            out, self.rbuf = self.rbuf[:bufsize], self.rbuf[bufsize:]
            return out
        if self.peer_closed:
            return b""
        raise BlockingIOError("暂时没有数据(真 socket 会在这里阻塞等)")

    def close(self):
        self.closed = True
        if self.peer is not None:
            self.peer.peer_closed = True


class Listener:
    def __init__(self):
        self.backlog = collections.deque()

    def accept(self):
        if not self.backlog:
            raise BlockingIOError("暂时没有新连接")
        return self.backlog.popleft()


def listen(net, port):
    lis = Listener()
    net.listeners[port] = lis
    return lis


def connect(net, port):
    if port not in net.listeners:
        raise ConnectionRefusedError(111, "Connection refused")
    cli = Endpoint("client")
    srv = Endpoint("server")
    cli.peer = srv
    srv.peer = cli
    net.listeners[port].backlog.append(srv)
    return cli


def ready(srvs):
    # 交回收缓冲里有数据的那几条连接的下标
    return [i for i, s in enumerate(srvs) if s.rbuf]


def serve_ready(srvs):
    # 给每条有数据的连接各回一段(echo),交回处理过的下标
    done = []
    for i, s in enumerate(srvs):
        if s.rbuf:
            s.sendall(s.recv(4096))
            done.append(i)
    return done

net = Net()
lis = listen(net, 9000)
conns = [connect(net, 9000) for _ in range(3)]
srvs = [lis.accept() for _ in range(3)]
conns[0].sendall(b"x")
conns[2].sendall(b"z")
print(",".join(str(i) for i in serve_ready(srvs)))
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论