2

I have created an echo server under UDP, and am working on a client that splits up a given file into packets and transfers it to a server, which then returns the packets to be reassembled by the client.

Sending the individual packets works just fine. However, I am trying to use the UDP_CORK socket option to transfer as many parts of the file as possible in one packet. I am working with the following code:

#define LINE_SIZE 80

...
// s = socket descriptor.
...

int one = 1;
int zero = 0;

setsockopt(s, IPPROTO_UDP, UDP_CORK, &one, sizeof(one));  // cork

/* Send to server, receive from server, write to new file. */

FILE *orig, *copy;
char line[LINE_SIZE];

if ((orig = fopen(input + 3, "rb")) == NULL) // original file
    print_error(input);

if ((copy = fopen(filename, "wb")) == NULL)  // copy of file
    print_error("fopen");

while (fread(line, sizeof(char), LINE_SIZE, orig) > 0) {
    if (sendto(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, len) == -1)
    print_error("sendto");
}

setsockopt(s, IPPROTO_UDP, UDP_CORK, &zero, sizeof(zero));  // uncork

if (recvfrom(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, &len) == -1)
    print_error("recvfrom");

fwrite(line, sizeof(char), LINE_SIZE, copy);

The server indicates that it is only receiving the one "normal-sized" packet, and not the corked packet that I would like. It follows that it is only sending back this one normal packet, received by the client via the recvfrom() call.

I am not sure that I set up the UDP_CORK correctly. Is the second argument correct? I am unfamiliar with what the second option truly means, as the man page was not entirely clear. It is also possible that I am misunderstanding how the cork works.

A few things to note:

  • I consider myself an intermediate-level programmer, but I have little network programming experience.
  • I realize that UDP is not the best to transfer files. This is eventually going to be adapted to a different protocol that I am helping to develop.

Thank you!

Cody
  • 135
  • 1
  • 3
  • 11

1 Answers1

1

How big is the file? You know that UDP datagrams are limited to 64K in size, right? And then anything over 1472 bytes (1500 bytes of available ethernet payload less minimum of 20 bytes of IP header, less 8 bytes of UDP header) is IP-fragmented.

Then you never check for the return value of the setsockopt(2). How do you know it's succeeding?

Then fread(3) tells you how much it read, but you still try to send LINE_SIZE bytes. This is wrong.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • That is quite right. I had not taken size into consideration, and the file that I was trying did not have a lot of descriptive bytes until much after the 1472 threshold. And thank you for pointing out my other missteps. However, when the datagram is IP-fragmented, shouldn't the rest be sent in one or more packets? I am only receiving the first. – Cody May 24 '12 at 21:52
  • The kernel might be refusing to pack more then MTU size into one datagram, and though I'm not sure about it, the fact that you receive the first chunk points in that direction. With fragmentation you don't get parts of the datagram - you either get the whole thing or nothing. – Nikolai Fetissov May 24 '12 at 21:56