0

I'm trying measure how long it takes to send a 1GB file from client to server using TCP socket in C. As of right now I manage to get the file from the client to the server and also print a "success" message, but I don't know where exactly I should put the function of time measuring since I only want it to start the count after the connection was made.

Also, I tried to send the file using a for loop, 5 times, but after the second time it gets "stuck". After each time the file gets to the server, it prints out a message. Inside the for loop it will only print 2 "success" messages. Is there any reason for this?

any tip or advice would be much appreciated!

server\measure.c

TCP/IP-server

#define SERVER_PORT 5060  //The port that the server listens
  
int main()
{
  
    // Open the listening (server) socket
    int listeningSocket = -1;  
     
    if((listeningSocket = socket(AF_INET , SOCK_STREAM , 0 )) == -1)
    {
        printf("Could not create listening socket : %d" 
#if defined _WIN32
        ,WSAGetLastError()
#else
        ,errno
#endif
        );
    }

    // Reuse the address if the server socket on was closed
    // and remains for 45 seconds in TIME-WAIT state till the final removal.
    //
    int enableReuse = 1;
    if (setsockopt(listeningSocket, SOL_SOCKET, SO_REUSEADDR, 
#if defined _WIN32
        (const char*)
#endif
        &enableReuse, 
        
        sizeof(int)) < 0)
    {
         printf("setsockopt() failed with error code : %d" , 

        );
    }

    // "sockaddr_in" is the "derived" from sockaddr structure
    // used for IPv4 communication. For IPv6, use sockaddr_in6
    //
    struct sockaddr_in serverAddress;
    memset(&serverAddress, 0, sizeof(serverAddress));

    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(SERVER_PORT);  //network order
      
    // Bind the socket to the port with any IP at this port
    if (bind(listeningSocket, (struct sockaddr *)&serverAddress , sizeof(serverAddress)) == -1)
    {
        printf("Bind failed with error code : %d" , 

    );
    // TODO: close the socket
        return -1;
    }
      
    printf("Bind() success\n");
  
    // Make the socket listening; actually mother of all client sockets.
    if (listen(listeningSocket, 500) == -1) //500 is a Maximum size of queue connection requests
                                            //number of concurrent connections 
    {
    printf("listen() failed with error code : %d"

    );
    // TODO: close the socket
        return -1;
    }
      
    //Accept and incoming connection
    printf("Waiting for incoming TCP-connections...\n");

    struct sockaddr_in clientAddress;  //
    socklen_t clientAddressLen = sizeof(clientAddress);


    //always listen
    while (1)
    {
        memset(&clientAddress, 0, sizeof(clientAddress));
        clientAddressLen = sizeof(clientAddress);
        int clientSocket = accept(listeningSocket, (struct sockaddr *)&clientAddress, &clientAddressLen);
        if (clientSocket == -1)
        {
           printf("listen failed with error code : %d"

            );
       // TODO: close the sockets


           return -1;
        }
      
        printf("A new client connection accepted\n");
  
        //Reply to client
        char message[] = "Welcome to our TCP-server\n";
        int messageLen = strlen(message) + 1;

        int bytesSent = send(clientSocket, message, messageLen, 0);
        if (-1 == bytesSent)
        {
            printf("send() failed with error code : %d" 

            );
        }
        else if (0 == bytesSent)
        {
           printf("peer has closed the TCP connection prior to send().\n");
        }
        else if (messageLen > bytesSent)
        {
           printf("sent only %d bytes from the required %d.\n", messageLen, bytesSent);
        }
        else 
        {
           printf("message 'welcome' was successfully sent .\n");
        }

    }
  
    
    return 0;
}

client.c

#define SERVER_PORT 5060
#define SERVER_IP_ADDRESS "10.0.2.15"
#define SIZE 10

int send_file(FILE *fp, int sockfd) {
    printf("in send File function\n");
    char *filename = "text.txt";

    fp = fopen(filename, "r");

    if (fp == NULL) {

        perror("[-]Error in reading file.");

        exit(1);

    }

    int n;

    char data[SIZE] = {0};

    int ans = 0;

    while (fgets(data, SIZE, fp) != NULL) {

        ans = send(sockfd, data, sizeof(data), 0);

        if (ans == -1) {
            perror("[-]Error in sending file.");
            exit(1);
        }

        bzero(data, SIZE);
    }
    printf("success send file\n");
    return ans;
}


int main() {

    char bufferReply[80] = {"\0"};
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    if (sock == -1) {
        printf("Could not create socket : %d"

        );
    }

    // "sockaddr_in" is the "derived" from sockaddr structure
    // used for IPv4 communication. For IPv6, use sockaddr_in6
    //
    struct sockaddr_in serverAddress;
    memset(&serverAddress, 0, sizeof(serverAddress));

    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(SERVER_PORT);
    int rval = inet_pton(AF_INET, (const char *) SERVER_IP_ADDRESS, &serverAddress.sin_addr);
    if (rval <= 0) {
        printf("inet_pton() failed");
        return -1;
    }

    struct sockaddr_in fromAddress;
    socklen_t fromAddressSize = sizeof(fromAddress);

    // Make a connection to the server with socket SendingSocket.

    if (connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == -1) {
        printf("connect() failed with error code : %d"

        );
    }

    printf("connected to server\n");

    int recv_len = recvfrom(sock, bufferReply, sizeof(bufferReply) - 1, 0, (struct sockaddr *) &fromAddress,
                            &fromAddressSize);
    if (recv_len == -1) {
        printf("recvfrom() failed with error code : %d", errno);
    } else
        printf("%s", bufferReply);


    for (int i = 0; i < 5; i++) {
        printf("i= %d\n", i);
        FILE *f = fopen("text.txt", "r");

        int bytesSent = send_file(f, sock);

        printf("after send i=%d\n",i);

        if (-1 == bytesSent) {
            printf("send() failed with error code : %d"
            );
        } else if (0 == bytesSent) {
            printf("peer has closed the TCP connection prior to send().\n");
        } else {
            printf("file was successfully sent .\n");
        }
    }
    return 0;
}
Sleeper
  • 47
  • 4
  • To determine how long a file transfer takes, simply get the current clock time before the 1st `send()`/`recv()` of the file, then get the new clock time after the last `send()`/`recv()` of the file, and then calculate the elapsed time between them. – Remy Lebeau Dec 16 '20 at 21:04
  • 1
    As for your code getting "stuck", that is because your socket I/O is all wrong to begin with. Use `recv()` instead of `recvfrom()`. Read data is not null-terminated. Your server is not reading any of the files the client sends, so the server's buffer is likely to fill up, blocking the sends. `fgets()` is the wrong function to use to read raw data of arbitrary files. And your server is leaking all of the sockets it accepts. – Remy Lebeau Dec 16 '20 at 21:04

0 Answers0