【问题标题】:Python36 and socketsPython36 和套接字
【发布时间】:2017-01-08 15:36:25
【问题描述】:

所以我使用 socket.connec 连接到 IRC 聊天

我通过 socket.send 传递我的变量来登录

登录成功,然后我使用 while true 循环 Socket.recv(1024)

如果我只是不断打印响应一切看起来都很好,但是假设我想添加到字符串的末尾...我注意到 socket.recv 并不总是得到完整的消息(最多只能抓取 1024正如预期的那样)并且消息的其余部分在循环的下一次迭代中。

这使得它无法逐行处理反馈。

有没有更好的方法来不断读取数据而不会被中继?是否可以在收到响应之前确定响应的大小,以便动态设置缓冲区?

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    TCP 是一种基于流的协议。缓冲接收到的字节,只从流中提取完整的消息。

    对于完整的行,在缓冲区中查找换行符。

    示例服务器:

    import socket
    
    class Client:
    
        def __init__(self,socket):
            self.socket = socket
            self.buffer = b''
    
        def getline(self):
            # if there is no complete line in buffer,
            # add to buffer until there is one.
            while b'\n' not in self.buffer:
                data = self.socket.recv(1024)
                if not data:
                    # socket was closed
                    return ''
                self.buffer += data
    
            # break the buffer on the first newline.
            # note: partition(n) return "left of n","n","right of n"
            line,newline,self.buffer = self.buffer.partition(b'\n')
            return line + newline
    
    srv = socket.socket()
    srv.bind(('',5000))
    srv.listen(1)
    conn,where = srv.accept()
    client = Client(conn)
    print(f'Client connected on {where}')
    while True:
        line = client.getline()
        if not line:
            break
        print(line)
    

    示例客户端:

    s=socket()
    s.connect(('127.0.0.1',5000))
    s.sendall(b'line one\nline two\nline three\nincomplete')
    s.close()
    

    服务器输出:

    Client connected on ('127.0.0.1', 2667)
    b'line one\n'
    b'line two\n'
    b'line three\n'
    

    【讨论】:

    • 尝试检查每一行以查看它是否以 \n 结尾或以 \r 结尾或以 \r\n 结尾,但没有一行。即使是完整的。尝试在解码 utf-8 之前和之后进行检查。我想知道我的 .splitlines() 方法是否正在杀死换行符
    • @AntonioAnonymous 是的,.splitlines() 删除换行符。您必须缓冲直到有换行符,然后处理缓冲区。我会更新一个例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2016-08-01
    • 2021-11-16
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多