【问题标题】:Reading a big chunk of data from Unix SOCK_STREAM socket从 Unix SOCK_STREAM 套接字读取大量数据
【发布时间】:2023-03-05 15:31:01
【问题描述】:

我是异步 I/O 的新手。 我需要从 Unix SOCK_STREAM 套接字中读取大量数据。我正在使用非阻塞套接字。 它可能需要不止一个 read/recv()。那部分对我来说很好。

我的疑问是—— 如果一次有 3-4 个客户端正在向我的服务器套接字写入大量数据,则表示每个客户端正在写入 100K 数据。 是否可能是我的第一次读取是从客户端 1 读取一些数据(例如 40 K),第二次读取是从客户端 2 读取数据,第三次读取是再次从客户端 1 读取剩余数据?

问候 DJ

【问题讨论】:

    标签: sockets unix asyncsocket


    【解决方案1】:

    您的问题的答案很大程度上取决于您如何将 client1 定义为 clientN。具体来说,它们是如何与服务器建立连接的。

    SOCK_STREAM 是面向连接的。这意味着您的服务器会创建一个侦听套接字并绑定到它,然后当客户端连接时,服务器会接受该连接并获得一个新的套接字。

    现在,如果 client1 到 clientN 将分别进行单独的连接,则服务器基本上会有 N 个不同的套接字,在这种情况下,您的问题的答案是否定的 - 来自不同客户端的数据不会混合,因为它们正在传输不同的套接字。

    但是,如果您有这样一种安排,即您有一个打开连接的父客户端,并且该套接字由 clients1 共享到 n(例如在不同的线程或子进程中),那么答案是肯定的 - 写在特定的套接字不是原子的,数据可以混合。

    附带说明,如果您使用 Unix 管道而不是 unix 域套接字,即使同一管道上的不同写入器达到一定阈值(根据 POSIX 至少为 512),您也将获得原子写入的好处, Linux 实际上支持 65000 字节)

    【讨论】:

    • 在这种情况下,不同客户端之间的操作将是原子的,因为每个客户端都在不同的套接字上运行。所以你的问题的答案是:不,数据不会混合。这些是不同的套接字。
    • 我的服务器正在使用 epoll 来轮询客户端。并且所有客户端都将有自己不同的连接,即您的情况 1. 客户端在其自己的启动期间打开一个连接,并且连接将完全保持打开状态。之后,客户端将继续发送大量数据。现在我的问题是——如果说 3 个客户端已将 100 KB 数据写入我的服务器,并假设我的服务器一次读取 50K。所以我将从 epoll 获得总共 6 个读取触发器。现在我的疑问是,是否会以正确的顺序触发,例如客户端 1 的触发器 1 和 2,客户端 2 的触发器 3 和 4,客户端 3 的触发器 5 和 6。
    • 不,您不能计算在不同套接字/客户端之间以任何特定顺序出现的触发器,仅与每个套接字本身有关。也就是说:client1 的第二个触发器总是在第一个触发器之后出现,但不能保证它会得到关于 client2 触发器的顺序
    • 所以,回答我的问题“这可能是我的第一次读取是从客户端 1 读取一些数据(比如 40 K)而第二次读取是从客户端 2 读取数据并且第三次读取再次读取的情况从 client1 读取剩余数据?”是是的。我对吗?所以,处理这种情况,我必须在客户端和数据之间保持某种映射,直到我没有完成从特定客户端读取整个数据。
    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 2014-06-07
    • 2017-09-30
    • 2016-04-11
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多