为了账号安全,请及时绑定邮箱和手机立即绑定

仅当线程进入睡眠状态时,使用自定义套接字 recvall 函数才有效

仅当线程进入睡眠状态时,使用自定义套接字 recvall 函数才有效

慕侠2389804 2023-12-20 14:07:05
我的本地网络上有以下套接字侦听:def recvall(sock):    BUFF_SIZE = 4096 # 4 KiB    fragments = []    while True:         chunk = sock.recv(BUFF_SIZE)        fragments.append(chunk)        # if the following line is removed, data is omitted        time.sleep(0.005)        if len(chunk) < BUFF_SIZE:             break            data = b''.join(fragments)    return datadef main():    pcd = o3d.geometry.PointCloud()    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.bind(('192.168.0.22', 2525))    print("starting listening...")    s.listen(1)    counter = 0    while True:        clientsocket, address = s.accept()        print(f"Connection from {address} has been established!")        received_data = recvall(clientsocket)        clientsocket.send(bytes(f"response nr {counter}!", "utf-8"))        counter += 1        print(len(received_data))if __name__ == "__main__":    main()172800我从手机上的应用程序向此端口发送字节长度的字节数据。正如您所看到的,我正在打印收到的数据量。time.sleep()仅当我按照上面的代码所示使用时,该金额才是正确的。如果我不使用这种方法,则只会收到一部分数据。显然这是一些计时问题,问题是:我怎样才能确保在不使用的情况下一直接收到所有数据time.sleep()(因为这也不是100%确定有效,具体取决于设置的睡眠时间)
查看完整描述

1 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

sock.recv()返回可用的数据。手册页中的相关部分recv(2)是:


The receive calls normally return any data available, up to the requested amount,

rather than waiting for receipt of the full amount requested.

在您的情况下,time.sleep(0.005)似乎允许消息的所有剩余数据到达并存储在缓冲区中。


有一些选项可以消除time.sleep(0.005). 哪一种最合适取决于您的需求。


sock.close()如果发送方发送数据,但不期望得到响应,您可以让发送方在发送数据后(即after )关闭套接字sock.sendall()。recv()将返回一个空字符串,可用于打破while接收器上的循环。

def recvall(sock):

    BUFF_SIZE = 4096

    fragments = []

    while True: 

        chunk = sock.recv(BUFF_SIZE)

        if not chunk:

            break

        fragments.append(chunk)

    return b''.join(fragments)

如果发送方发送固定长度(例如172800字节)的消息,则可以recv()循环使用,直到接收方收到完整的消息。

def recvall(sock, length=172800):

    fragments = []

    while length:

        chunk = sock.recv(length)

        if not chunk:

            raise EOFError('socket closed')

        length -= len(chunk)

        fragments.append(chunk)

    return b''.join(fragments)

其他选项包括:在发送方发送的消息末尾添加分隔符,例如不能成为数据一部分的特殊字符;然后接收器可以recv()循环运行,直到检测到分隔符和 b。在发送方的消息前面加上消息的长度前缀;然后接收者就会知道每条消息需要多少字节。


查看完整回答
反对 回复 2023-12-20
  • 1 回答
  • 0 关注
  • 45 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信