-2

Usually when sending arbitrarily sized packets, a maximum is established and used as the size of your receive buffer.

#include <winsock2.h>

// Socket Description
// Hint.ai_family = AF_INET;
// Hint.ai_socktype = SOCK_DGRAM;
// Hint.ai_protocol = IPPROTO_UDP;

void Send(int Size)
{
    char *Data = (char *)malloc(Size);
    sendto(Socket, Data, Size, NULL, Result->ai_addr, Result->ai_addrlen)
}

void Receive()
{
    const unsigned int MaxDataSize = 1436;
    char *Data = (char *)malloc(MaxDataSize);
    recvfrom(Socket, Data, MaxDataSize, 0, (SOCKADDR*)&RecvAddr, &RecvAddrSize);
}

In this pseudo example, no matter the size of data passed to Send(), our Receive() function always gets it at the maximum size defined.

How can one ascertain the original sent packets size?

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
KKlouzal
  • 732
  • 9
  • 32
  • You need to provide more context, like what kind of socket is it? What is the size of the data you send? And you *do* check the result of `sendto` and `recvfrom`? Also, this is pretty much unrelated to C++ (or you would use `new` instead of `malloc`) so please update the tags. Tag spamming is frowned upon. – Some programmer dude Jul 12 '16 at 08:01
  • 3
    Have you considered consulting the [*man* page for *recvfrom()*](http://linux.die.net/man/2/recvfrom)? – user207421 Jul 12 '16 at 08:01
  • 2
    `recvfrom` returns the size of the packet... – user253751 Jul 12 '16 at 08:10
  • Thanks guys I completely overlooked the return value. I'm sure someone else will stumble here in the future as I did. – KKlouzal Jul 12 '16 at 08:41

1 Answers1

0

MSDN recvfrom() Documentation

If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Subsequently, through the use of the MSG_PEEK flag:

Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function subsequently returns the amount of data that can be read in a single call to the recvfrom (or recv) function, which may not be the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the recvfrom (or recv) function is limited to the data size written in the send or sendto function call.

This gives you the flexibility to read an incoming packet in multiple bursts. Allowing you to append a size value to the beginning of a packet before sending it off. This however does not seem as trivial as it sounds.

I question any performance gains from going this route instead of just allocating enough memory outright to hold the biggest packet you'll ever send.

KKlouzal
  • 732
  • 9
  • 32
  • Your question was "How can one ascertain the original sent packets size?". This has got nothing to do with the size of the receive buffer; you've missed the point. You can't tell the receiver just to fill up the receive buffer, or to read the whole packet, whatever that means. You *must* read the incoming packet in multiple bursts, period. The size of the receive buffer is not an issue. – EML Jul 12 '16 at 14:33
  • 1
    @EML: what you say is true for TCP, but not for UDP. UDP preserves message boundaries, where a single call to `sendto()` (or a connected `send()`) sends a complete message, and a single call to `recvfrom()` (or a connected `recv()`) reads a complete message and returns its full size. If the buffer is not large enough to receive the complete message in a single read, a `WSAEMSGSIZE` error is reported and the message is lost, unless `MSG_PEEK` is used. There is no need to embed the actual message length inside a UDP message's payload, except maybe for integrity checking. – Remy Lebeau Jul 12 '16 at 20:20
  • @Remy - I didn't notice the UDP/DGRAM comment - thanks - answer withdrawn. – EML Jul 12 '16 at 20:50