0

I want to get away from the sequential and slow way of reading from a socket, in which we use:

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);

That means, if the client sends me PACKET_STRUCT (Packet #1) and another PACKET_STRUCT (Packet #2) -- I would have to read Packet #1 before I am able to read from Packet #2.

Is there a way where I can offset in the recvfrom, starting at the sizeof(PACKET_STRUCT) in which I would be able to read Packet #2 without reading Packet #1?

And so on sizeof(PACKET_STRUCT)*2 to read Packet #3.

I understand there is a pread() that allows for reading a file descriptor at a certain offset, but I would like to keep the MSG_PEEK flag.

There is also an lseek() function that sets the position of the file descriptor, but I will be having several worker threads reading on that file descriptor (and I would prefer not to use a mutex as that is also sequential.)

So my question is, is there a recvmsg-similar function with an offset and MSG_PEEK flags?

Lucky
  • 579
  • 6
  • 24

1 Answers1

0

There's no concept of seeking or skipping data on a socket, so you can't do that. (lseek/pread can't be used on sockets)

Some platforms lets you receive many datagrams in one call though, using the recvmmsg, if you don't care about the first message - just receive and ignore it.

nos
  • 223,662
  • 58
  • 417
  • 506
  • Really great! Seeing as non-blocking recvmmsg() returns immediately but also returns the number of messages sent. Then I will be able to have workers mine through that mmsghdr struct. – Lucky Nov 21 '13 at 23:56
  • But seeing as recvmmsg() is an extension of recvmsg(). Isn't it just the same to use recvmsg() then send a worker off to work on that buffer? Or are there more speed benefits from using recvmmsg() depending on how we optimize it? – Lucky Nov 21 '13 at 23:57
  • @Lucky since you can read many messages in one system call, you can avoid doing a lot of system calls - which can be a huge win. And if you then structure your workers so you can hand off many packets at a time to them, which might be easier when using recvmmsg(), you benefit from that too (as buffering up messages and having workers process several of them in one go creates less overhead). This is assuming you're using UDP. For TCP, you'd read a large buffer each time, and parse out all the full messages you've read, and process those - don't try to read one small "message" at a time – nos Nov 22 '13 at 00:10