0

This is more of a request for confirmation than a question, so I'll keep it brief. (I am away from my PC and so can't simply implement this solution to test).

I'm writing a program to send an image file taken via webcam (along with meta data) from a raspberryPi to my PC.

I've worked out that the image is roughly around 130kb, the packet header is 12b and the associated meta data another 24b. Though I may increase the image size in future, once I have a working prototype.

At the moment I am not able to retrieve this whole packet successfully as, after sending it to the PC I only ever get approx 64kb recv'd in the buffer.

I have assumed that this is because for whatever reason the default buffer size for a socket declared like:

SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);

is 64kb (please could someone clarify this if you're 'in the know')

So - to fix this problem I intend to increase the socket size to 1024kb via the setsockopt(x..) command.

Please could someone confirm that my diagnosis of the problem, and proposed solution are correct?

I ask this question as I am away form my PC right now and am unable to try it until I get back home.

Catch_0x16
  • 187
  • 1
  • 4
  • 13
  • The other alternative I am mentally priming myself for is to manually segment the packet. However this would, I suspect, introduce much more potential for error and would increase overall packet size/computation time as I would need to send and read a header for each individual segment. – Catch_0x16 Sep 29 '16 at 09:13
  • It is London to a brick that the reason you aren't receiving all the data is that you are assuming that `recv()` fills your buffer instead of looping. There is nothing in the documentation to support that assumption. – user207421 Sep 29 '16 at 10:13
  • Thanks for the response, not 100% sure I follow you, but to clarify: I know the size of incoming data because it is stored in the header and this is extracted, read, and a suitably sized buffer allocated to receive the rest of the data. So, in further explanation: >Get header, with data packet size >Create buffer of correct size >Run recv to fill the buffer and make a note of bytes received >Check bytes received against data size in header – Catch_0x16 Sep 29 '16 at 13:13

1 Answers1

1

This most likely has nothing to do with the socket buffers, but with the fact that recv() and send() do not have to receive and send all the data you want. Check the return value of those function calls, it indicates how many bytes have actually been sent and received.

The best way to deal with "short" reads/writes is to put them in a loop, like so:

char *buf;  // pointer to your data
size_t len; // length of your data
int fd;     // the socket filedescriptor

size_t offset = 0;
ssize_t result;
while (offset < len) {
  result = send(fd, buf + offset, len - offset, 0);
  if (result < 0) {
     // Deal with errors here
  }
  offset += result;
}

Use a similar construction for receiving data. Note that one possible error condition is that the function call was interrupted (errno = EAGAIN or EWOULDBLOCK), in that case you should retry the send command, in all other cases you should exit the loop.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
  • Thanks @G.Sliepen. So, I see that you are sending in a loop, and thus suggesting (please correct me if not) that on the receiving end, a looping recv should be used. -- What is the protection against recv'ing data that is not intended, like an incidental packet sent to the port from an unrelated program? The only way I can think of doing this would be to put a header with a 'part 10 of 20' type ID inside it. Does this not seem to create more issues? -- I guess my main question is that can I not just increase the size of the internal system buffer that send/recv use? i.e. setsockopt... – Catch_0x16 Sep 29 '16 at 13:19
  • Yes, you should use a receive loop on the receiving end. TCP sockets (which I assume is what you are using) always provide an ordered stream of data from a single connection. So you won't receive spurious data from an unrelated network connection, and you will see all data coming in in the same order as it is sent. – G. Sliepen Sep 29 '16 at 18:23