【问题标题】:Reading from a socket at an offset with MSG_PEEK flag?从带有 MSG_PEEK 标志的偏移量处读取套接字?
【发布时间】:2013-11-21 23:07:49
【问题描述】:

我想摆脱从我们使用的套接字读取的顺序和缓慢的方式:

struct PACKET_STRUCT{
   int PacketType;
   char buffer[50];
};

char buffer[sizeof(PACKET_STRUCT)];
struct sockaddr_storage addr;
socklen_t fromlen = sizeof(addr);
int iByteCount = recvfrom(CProperties->m_iSocket, buffer, sizeof (buffer), MSG_PEEK, (struct sockaddr*)&addr, &fromlen);

这意味着,如果客户端向我发送 PACKET_STRUCT(数据包 #1)和另一个 PACKET_STRUCT(数据包 #2)——我必须先读取数据包 #1,然后才能读取数据包 #2。

有没有一种方法可以让我在 recvfrom 中进行偏移,从 sizeof(PACKET_STRUCT) 开始,这样我就可以在不读取 Packet #1 的情况下读取 Packet #2?

依此类推 sizeof(PACKET_STRUCT)*2 读取数据包 #3。

我知道有一个 pread() 允许读取某个偏移量的文件描述符,但我想保留 MSG_PEEK 标志。

还有一个 lseek() 函数可以设置文件描述符的位置,但我将有几个工作线程读取该文件描述符(我不希望使用互斥锁,因为这也是顺序的。)

所以我的问题是,是否有一个带有偏移量和 MSG_PEEK 标志的类似 recvmsg 的函数?

【问题讨论】:

    标签: c++ sockets networking udp bsd


    【解决方案1】:

    没有在套接字上查找或跳过数据的概念,因此您不能这样做。 (lseek/pread 不能用于套接字)

    如果您不关心第一条消息,但某些平台允许您在一次调用中接收多个数据报,使用 recvmmsg - 只需接收并忽略它。

    【讨论】:

    • 真的很棒!看到非阻塞 recvmmsg() 立即返回,但也返回发送的消息数。然后我将能够通过该 mmsghdr 结构让工人开采。
    • 但是将 recvmsg() 看作是 recvmsg() 的扩展。使用 recvmsg() 然后派一个工人去处理那个缓冲区不是一样吗?或者根据我们如何优化它,使用 recvmmsg() 是否有更多的速度优势?
    • @Lucky 因为您可以在一个系统调用中读取许多消息,所以您可以避免执行大量系统调用 - 这可能是一个巨大的胜利。然后,如果您构建您的工作人员,以便您可以一次将多个数据包交给他们,这在使用 recvmmsg() 时可能会更容易,您也可以从中受益(因为缓冲消息并让工作人员一次处理其中的几个产生更少的开销)。这是假设您使用的是 UDP。对于 TCP,您每次都会读取一个大缓冲区,并解析出您已读取的所有完整消息并处理这些消息 - 不要尝试一次读取一个小“消息”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2020-05-26
    • 2012-10-20
    • 1970-01-01
    • 2021-04-04
    • 2023-01-27
    相关资源
    最近更新 更多