繁体   English   中英

Python套接字同时接收多个消息

[英]Python socket receiving multiple messages at the same time

我正在使用python(3)套接字进行TCP / IP聊天,并且在socket.send / socket.receive对的多个实例上遇到了相同的问题。 举个例子:

每次服务器更新已连接客户端的列表时,它首先发送一个字符串信号表示即将这样做,逐个发送列表,然后发送另一个字符串信号表示已完成。 在客户端,我有一个线程来接收消息并处理它们,并且它具有处理这种特定字符串信号的特定情况。 在这种情况下,它将启动一个循环以接收客户端名称,直到收到表示客户端列表已结束的信号。

通常,尽管不总是这样,但是客户端名称或字符串信号或两者都混合为单个消息。 如果我有客户C1,C2,C3,并发送“ over”信号说列表已完成,则我的列表可能显示如下内容:

C1C2
C3
“过度”

由于客户端只有这个线程和GUI / Main线程,而服务器端没有其他类型的消息混杂在一起(在用于侦听,处理客户端和GUI / Main的线程上),我假设它不是同步的问题。 我尝试在信号和列表之间添加大小可变的time.sleep()函数,但是仍然会发生。

我在整个套接字聊天的整个过程中都注意到了这一点,但是能够找出解决方法(通常使用sleep()),但是这一点让我感到困惑。 我是否在做一些根本上错误的事情,弄乱了我发送和接收的消息? 如何保证在每个socket.send()上发送单个数据?

TCP是字节流协议。 没有消息,只有一堆字节进来。您必须实现协议并缓冲接收到的数据,直到知道完整的消息为止。

您可以使用内置的socket.makefile()方法来实现面向行的协议。 例:

server.py

from socket import *

s = socket()
s.bind(('',5000))
s.listen(1)

while True:
    c,a = s.accept()
    print(f'connect: {a}')
    read  = c.makefile('r')
    write = c.makefile('w')

    with c,read,write:
        while True:
            data = read.readline()
            if not data: break
            cmd = data.strip()
            print(f'cmd: {cmd}')
            if cmd == 'LIST':
                write.write('C1\nC2\nC3\nDONE\n')
                write.flush()

    print(f'disconnect: {a}')

client.py

from socket import *

s = socket()
s.connect(('localhost',5000))
read = s.makefile('r',)
write = s.makefile('w')

def send(cmd):
    print(cmd)
    write.write(cmd + '\n')
    write.flush()

with s,read,write:
    send('TEST')
    send('LIST')
    while True:
        data = read.readline()
        if not data: break
        item = data.strip()
        if item == 'DONE': break
        print(f'item: {item}')
    send('OTHER')

服务器输出:

connect: ('127.0.0.1', 13338)
cmd: TEST
cmd: LIST
cmd: OTHER
disconnect: ('127.0.0.1', 13338)

客户输出:

TEST
LIST
item: C1
item: C2
item: C3
OTHER

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM