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

我的本地网络上有以下套接字侦听:


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 data


def 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%确定有效,具体取决于设置的睡眠时间)


慕侠2389804
浏览 46回答 1
1回答

幕布斯6054654

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):&nbsp; &nbsp; BUFF_SIZE = 4096&nbsp; &nbsp; fragments = []&nbsp; &nbsp; while True:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; chunk = sock.recv(BUFF_SIZE)&nbsp; &nbsp; &nbsp; &nbsp; if not chunk:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; fragments.append(chunk)&nbsp; &nbsp; return b''.join(fragments)如果发送方发送固定长度(例如172800字节)的消息,则可以recv()循环使用,直到接收方收到完整的消息。def recvall(sock, length=172800):&nbsp; &nbsp; fragments = []&nbsp; &nbsp; while length:&nbsp; &nbsp; &nbsp; &nbsp; chunk = sock.recv(length)&nbsp; &nbsp; &nbsp; &nbsp; if not chunk:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise EOFError('socket closed')&nbsp; &nbsp; &nbsp; &nbsp; length -= len(chunk)&nbsp; &nbsp; &nbsp; &nbsp; fragments.append(chunk)&nbsp; &nbsp; return b''.join(fragments)其他选项包括:在发送方发送的消息末尾添加分隔符,例如不能成为数据一部分的特殊字符;然后接收器可以recv()循环运行,直到检测到分隔符和 b。在发送方的消息前面加上消息的长度前缀;然后接收者就会知道每条消息需要多少字节。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python