C uses TCP protocol for file transfer

C uses TCP protocol for file transfer TOC

How to achieve it

1. The server program creates a TCP server socket, binds it to a specific IP address and port, and starts listening to the client’s connection request.

2. The client program creates a TCP client socket and connects to the server’s IP address and port.

3. The client sends the name of the file to be transferred to the server. After receiving the file name, the server judges whether the file exists. If it exists, it replies to the client and sends the file size to the client.

4. After the client receives the reply from the server and obtains the file size, it starts sending the file data. The client can read the file data through a loop, and call the send() function to send the data to the server.

5. After the server receives the data sent by the client, it writes the data into the file. The server can receive data through a loop, and call the write() function to write the data to a file.

6. After the client has sent all the data, close the socket and notify the server that the file transfer has been completed. After receiving the data sent by the client, the server closes the socket.

Note

1. In the process of file transfer, the integrity and accuracy of the data need to be considered, and the correctness of the transferred data can be verified by calculating the checksum or using the hash algorithm.

2. When the file to be transferred is large, it needs to be transferred in batches, which can be carried out by means of block transfer.

3. Before the data is transmitted, the data needs to be encapsulated and some meta information is added for transmission control and data verification.

4. When writing programs, it is necessary to consider issues such as network delay and packet loss, and use appropriate methods for retransmission or compensation.

5. Issues such as data security and encryption and decryption during transmission need to be considered when transferring files.

Upload the code directly

Server program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 8888

int main()
{<!-- -->
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);

    // create TCP server socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {<!-- -->
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Set socket options to allow reuse of address and port
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                    &opt, sizeof(opt)))
    {<!-- -->
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    // set address and port
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // bind the socket to a specific address and port
    if (bind(server_fd, (struct sockaddr *) & address,
             sizeof(address)) < 0)
    {<!-- -->
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // Start listening for client connection requests
    if (listen(server_fd, 3) < 0)
    {<!-- -->
        perror("listen");
        exit(EXIT_FAILURE);
    }

    printf("Waiting for connections...\\
");

    // wait for client connection
    if ((new_socket = accept(server_fd, (struct sockaddr *) & amp;address,
                             (socklen_t *) & amp; addrlen)) < 0)
    {<!-- -->
        perror("accept");
        exit(EXIT_FAILURE);
    }

    printf("Connection accepted.\\
");

    // Receive the file name sent by the client
    char filename[1024];
    valread = read(new_socket, filename, 1024);
    if (valread < 0)
    {<!-- -->
        perror("read");
        exit(EXIT_FAILURE);
    }

    printf("Received filename: %s\\
", filename);

    // open the file and get the file size
    FILE *fp;
    if ((fp = fopen(filename, "rb")) == NULL)
    {<!-- -->
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    fseek(fp, 0, SEEK_END);
    int file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // Reply to the client and send the file size
    char filesize_str[32];
    sprintf(filesize_str, "%d", file_size);
    valread = send(new_socket, filesize_str, strlen(filesize_str), 0);
    if (valread < 0)
    {<!-- -->
        perror("send");
        exit(EXIT_FAILURE);
    }

    // send file data
    char buffer[1024];
    int bytes_read;
    while ((bytes_read = fread(buffer, 1, 1024, fp)) > 0)
    {<!-- -->
        if (send(new_socket, buffer, bytes_read, 0) != bytes_read)
        {<!-- -->
            perror("send");
            exit(EXIT_FAILURE);
        }
    }

    fclose(fp);
    close(new_socket);
    close(server_fd);

    printf("File transfer completed.\\
");

    return 0;
}

Client program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 8888

int main(int argc, char const *argv[])
{<!-- -->
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char buffer[1024] = {<!-- -->0};

    // Create a TCP client socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {<!-- -->
        printf("\\
 Socket creation error \\
");
        return -1;
    }

    memset( &serv_addr, '0', sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert the IP address from dotted decimal to binary form
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
    {<!-- -->
        printf("\\
Invalid address/ Address not supported \\
");
        return -1;
    }

    // connect to server
    if (connect(sock, (struct sockaddr *) & amp;serv_addr, sizeof(serv_addr)) < 0)
    {<!-- -->
        printf("\\
Connection Failed \\
");
        return -1;
    }

    // send filename
    char *filename = "test.jpg";
    valread = send(sock, filename, strlen(filename), 0);
    if (valread < 0)
    {<!-- -->
        perror("send");
        return -1;
    }

    // receive file size
    char filesize_str[32];
    valread = read(sock, filesize_str, 32);
    if (valread < 0)
    {<!-- -->
        perror("read");
        return -1;
    }
    int file_size = atoi(filesize_str);

    // receive file data
    FILE *fp;
    if ((fp = fopen("recv.jpg", "wb")) == NULL)
    {<!-- -->
        perror("fopen");
        return -1;
    }
    int bytes_received = 0;
    int bytes_left = file_size;
    while (bytes_left > 0)
    {<!-- -->
        int bytes_to_receive = bytes_left < 1024 ? bytes_left : 1024;
        bytes_received = read(sock, buffer, bytes_to_receive);
        if (bytes_received < 0)
        {<!-- -->
            perror("read");
            return -1;
        }
        fwrite(buffer, 1, bytes_received, fp);
        bytes_left -= bytes_received;
    }

    fclose(fp);
    close(sock);

    printf("File transfer completed.\\
");

    return 0;
}