0

I Want to measure how much time takes for each socket to transfer 100MB data file so I implement many of sockets type like TCP, some pipe's mmaps etc..

The process to measure is (on the client side )::= before I send the data I take time and after the data is sent I stop the time.

(On the Server side ) ::= before I receive the data I take time and after the file is written I take again time.

the problem is on the server side I never out from the while loop in UDP / UDS Dgram

so I never can measure the time it takes to transfer data between them.

For example here is half of my server the while part in UDP ipv6 server:

clock_t start = 0, end = 0;
FILE *fp;
char *filename = "new_data.txt";
fp = fopen(filename, "w");
/* now wait until we get a datagram */
printf("waiting for a datagram...\n");
clilen = sizeof(client_addr);
start = clock();

while (1) {
    ssize_t bytes = recvfrom(sock, buffer, 1024, 0,
                             (struct sockaddr *) &client_addr,
                             &clilen);
    if (bytes < 0) {
        perror("recvfrom failed");
        exit(4);
    }
    fprintf(fp, "%s", buffer);
    bzero(buffer, 1024);

}
close(sock);
//fclose(fp);
end = clock();
double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Receive in %f seconds\n", cpu_time_used);
ATB
  • 119
  • 1
  • 9
  • You could make the first byte of your UDP packet mean something ... e.g. 0 for more packets to come, 1 means last packet. And check that. Just hope you don't drop the last packet though. – pmacfarlane Dec 06 '22 at 14:25
  • @pmacfarlane Well, I tried something like that but Unfortunately I didn't succeed with it maybe I did it wrong, how I can do it? – ATB Dec 06 '22 at 14:28
  • In the client, set your buffer to all zero, and send all but the last packet like that. For the last packet, set buffer[0]=1 and send it. Then change your while loop in the server to while(buffer[0] == 0). – pmacfarlane Dec 06 '22 at 14:46
  • @pmacfarlane Understood, but my file data is random so if in the some of buffer[0] it will be 1? you understand the problem? – ATB Dec 06 '22 at 14:56
  • If you don't care about the data being correct, you could just overwrite the first byte with 0 (or 1). You'll still be timing how long it takes to read and send the data, but it will be corrupted. Note that your current server code is not correctly writing the data to a file anyway, fprintf() is not what you need here. – pmacfarlane Dec 06 '22 at 14:58
  • I need to calculate the checksum of the file so it must be correct, so what I need? – ATB Dec 06 '22 at 15:01
  • You need fwrite(), and use the correct number of bytes that was received. You don't need the bzero(). You could reserve the first byte of your buffer as a flag byte, and read your file data into buffer+1, to get correct data transfer and a flag. – pmacfarlane Dec 06 '22 at 15:03
  • @pmacfarlane the first part understand, i change it to fwrite(), but I didn't understand the second part why i dont need the bzero and how I can reserve the first byte of my buffer as a flag? – ATB Dec 06 '22 at 15:08

1 Answers1

1

One way to solve it would be to have an extra byte in your buffer that is a flag that indicates if there is any more data to come after this packet. Clear the flag when there is more data, set the flag when there is not. Something like:

Client:

#define CHUNK_SIZE 1024
char buffer[CHUNK_SIZE + 1] = { 0 };

while ((num_bytes = fread(buffer + 1, 1, CHUNK_SIZE, fp)) > 0)
{
    sendto(..., buffer, 1 + num_bytes, ...);
}

buffer[0] = 1;
sendto(sock, buffer, 1, ...);

Server:

// Same chunk size and buffer as above

while ((num_bytes = recvfrom(sock, buffer, CHUNK_SIZE + 1, ...)) > 0)
{
    if (num_bytes > 1)
    {
        fwrite(buffer + 1, 1, num_bytes - 1, fp);
    }
    if (buffer[0] == 1)
        break;
}

There are other ways, such as having a TCP control socket running at the same time, over which you send out-of-band messages to indicate when the transmission is finished, but that is much more complex.

pmacfarlane
  • 3,057
  • 1
  • 7
  • 24
  • Well works like Magic, but one problem is you know why the checksum is not the same? I calculate the checksum before and after and is a little different – ATB Dec 06 '22 at 16:41
  • UDP is unreliable - you might be dropping packets. Make both your programs count how many bytes they send and receive, and print that to see if they are different. If you are dropping packets, you'd be better using TCP. Or as a quicker check, look at the file lengths. – pmacfarlane Dec 06 '22 at 16:45
  • @pmarcfarlane Yeah, understand but the funny is I implement already TCP socket the check sum is too different from the original :( – ATB Dec 06 '22 at 16:54
  • I guess that would be a separate question that you could post then. Were you using fprintf() instead of fwrite() in your TCP version? – pmacfarlane Dec 06 '22 at 16:55
  • https://stackoverflow.com/questions/74706537/tcp-send-a-file-data-from-client-to-server-problem-different-checksum-on-file – ATB Dec 06 '22 at 17:11
  • when i change it to fwrite() its writes only the first line same as the original file and the rest in NULL and the checksum equals... weird – ATB Dec 06 '22 at 17:26
  • I'm going to guess your client code here also uses fgets() instead of fread(). Hopefully changing that will fix things. – pmacfarlane Dec 06 '22 at 19:15