Under Linux, based on TCP and UDP protocols, single-threaded communication server under different processes

C language implements single-thread communication server under different processes based on TCP and UDP protocols under Linux

1. TCP single-thread communication server

  • Run the server first, then the client
  • Enter “exit” to exit

1.1 server_TCP.c

**#include <my_head.h>

#definePORT 6666
#define IP "192.168.125.103"

int main(int argc, const char *argv[])
{<!-- -->
    // Create streaming socket
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0)
    {<!-- -->
        ERR_MSG("socket");
        return -1;
    }
    printf("Socket created successfully server_fd = %d\\
", server_fd);

    //Allow ports to be reused quickly
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, & amp;reuse, sizeof(reuse)) < 0)
    {<!-- -->
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("Allow port fast reuse successfully\\
");

    //The address information of the binding server must be bound
    struct sockaddr_in server_in; // Information used to bind this host
    server_in.sin_family = AF_INET; // AF_INET is required
                                               // Because the streaming socket was created earlier using IPv4
    server_in.sin_port = htons(PORT); //Specify port number
    server_in.sin_addr.s_addr = inet_addr(IP); // Bind local IP
    if (bind(server_fd, (struct sockaddr *) & amp;server_in, sizeof(server_in)) < 0)
    {<!-- -->
        ERR_MSG("bin");
        return -1;
    }
    printf("bind successful\\
");

    // Convert the socket to passive listening state
    if (listen(server_fd, 256) < 0)
    {<!-- -->
        ERR_MSG("listen");
        return -1;
    }
    printf("listen successfully\\
");

    // Get the client information of successful connection and generate a new file descriptor
    // This file descriptor is the file descriptor used to communicate with the client
    struct sockaddr_in client_in; // Used to store received client information
    socklen_t addrlen = sizeof(client_in); // Used to store the length of information sent from the client
    int new_fd = accept(server_fd, (struct sockaddr *) & amp;client_in, & amp;addrlen); // Connect client
    if (new_fd < 0)
    {<!-- -->
        ERR_MSG("accept");
        return -1;
    }
    printf("new_fd = %d __%d__\\
", new_fd, __LINE__);

    // Output client IP and port number
    printf("client IP = %s\\
", inet_ntoa(client_in.sin_addr));
    printf("client port = %d\\
", ntohs(client_in.sin_port));

    //  Receive data
    char buff[128];
    ssize_t res = 0;
    while (1)
    {<!-- -->
        // Clear the temporary storage area
        bzero(buff, sizeof(buff));
        // Receive data When the last parameter is 0, you can also use read
        // res = recv(new_fd, buff, sizeof(buff), 0);
        res = read(new_fd, buff, sizeof(buff));
        if (res < 0)
        {<!-- -->
            ERR_MSG("recv");
            return -1;
        }
        // The write end is closed, that is, the client is closed
        else if (0 == res)
        {<!-- -->
            printf("[ %s : %d ] Client disconnected\\
", inet_ntoa(client_in.sin_addr),
                   ntohs(client_in.sin_port));
            break;
        }
        // Output client information and received data
        printf("[ %s : %d ] [massage : %s ]\\
", inet_ntoa(client_in.sin_addr),
               ntohs(client_in.sin_port), buff);

        //The data received is exit (exit)
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }

        //  send data
        //Send message to client
        printf("reply:");
        scanf("%s", buff);
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }
        //  send
        if (send(new_fd, buff, sizeof(buff), 0) < 0)
        {<!-- -->
            ERR_MSG("send");
            return -1;
        }
        printf("buff = %s\\
", buff);
        putchar(10);
    }

    //Close socket
    close(server_fd);
    close(new_fd);
    return 0;
}

1.2 client_TCP.c

#include <my_head.h>

#define SERVER_PORT 6666 // Server port number
#define SERVER_IP "192.168.125.103" // Server IP

int main(int argc, const char *argv[])
{<!-- -->
    //Create client streaming socket
    int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd < 0)
    {<!-- -->
        ERR_MSG("socket");
        return -1;
    }
    printf("Socket created successfully client_fd = %d\\
", client_fd);

    // Port quick reuse
    int reuse = 1;
    if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, & amp;reuse, sizeof(reuse)) < 0)
    {<!-- -->
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("Allow port fast reuse successfully\\
");

    // Bind client information. Binding is not required. It is recommended not to bind.
    // If not bound, the operating system will automatically assign a port number

    //  connect to the server
    struct sockaddr_in server_in;
    server_in.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_in.sin_port = htons(SERVER_PORT);
    server_in.sin_family = AF_INET;
    //  connect
    if (connect(client_fd, (struct sockaddr *) & amp;server_in, sizeof(server_in)) < 0)
    {<!-- -->
        ERR_MSG("connect");
        return -1;
    }

    char buff[128];
    ssize_t res = 0;
    while (1)
    {<!-- -->
        //  Send a message
        printf("Please enter: ");
        fgets(buff, sizeof(buff), stdin);
        buff[strlen(buff) - 1] = 0;
        if (send(client_fd, buff, sizeof(buff), 0) < 0)
        {<!-- -->
            ERR_MSG("send");
            return -1;
        }
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Broken link\\
");
            break;
        }

        printf("Sent successfully\\
");

        bzero(buff, sizeof(buff));

        //Receive message
        res = recv(client_fd, buff, sizeof(buff), 0);
        if (res < 0)
        {<!-- -->
            ERR_MSG("recv");
            return -1;
        }
        else if (0 == res)
        {<!-- -->
            printf("[ %s : %d ] Server disconnected __%d__\\
", SERVER_IP, SERVER_PORT, __LINE__);
            break;
        }
        printf("[ %s : %d ] [massage : %s ]\\
", SERVER_IP, SERVER_PORT, buff);
    }

    close(client_fd);
    return 0;
}

2. TCP single-thread communication server

  • Run the server first, then the client
  • Enter “exit” to exit

2.1 server_UDP.c

#include <my_head.h>

#define SERVER_PORT 6666
#define SERVER_IP "192.168.125.103"

int main(int argc, const char *argv[])
{<!-- -->
    //Create a report socket
    int client_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (client_fd < 0)
    {<!-- -->
        ERR_MSG("socket");
        return -1;
    }
    printf("Socket created successfully client_fd = %d\\
", client_fd);

    //Allow ports to be reused quickly
    int reuse = 1;
    if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, & amp;reuse, sizeof(reuse)) < 0)
    {<!-- -->
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("Allow port fast reuse successfully\\
");

    // Bind client information. Binding is not required. It is recommended not to bind.
    // If not bound, the operating system will automatically assign a port number

    //Specify server information
    struct sockaddr_in server_addr; // Information used to bind this host
    server_addr.sin_family = AF_INET; // AF_INET is required
                                                        // Because the report socket was created earlier using IPv4
    server_addr.sin_port = htons(SERVER_PORT); //Specify port number
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // Bind local IP

    //  send data
    char buff[128];
    ssize_t res = 0;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    while (1)
    {<!-- -->
        // Clear the temporary storage area
        bzero(buff, sizeof(buff));
        //  send data
        //Send message to client
        printf("Please enter: ");
        scanf("%s", buff);
        
        //  send
        if (sendto(client_fd, buff, sizeof(buff), 0, (struct sockaddr *) & amp;server_addr, sizeof(server_addr)) < 0)
        {<!-- -->
            ERR_MSG("sendto");
            return -1;
        }
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }
        printf("buff = %s\\
", buff);

        // Receive data When the last parameter is 0, you can also use read
        // res = recv(client_fd, buff, sizeof(buff), 0);
        // res = read(client_fd, buff, sizeof(buff));
        res = recvfrom(client_fd, buff, sizeof(buff), 0, (struct sockaddr *) & amp;client_addr, & amp;client_len);
        if (res < 0)
        {<!-- -->
            ERR_MSG("recv");
            return -1;
        }

        // Output client information and received data
        printf("[ %s : %d ] [massage : %s ]\\
", inet_ntoa(client_addr.sin_addr),
               htons(client_addr.sin_port), buff);

        //The data received is exit (exit)
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }

        putchar(10);
    }

    //Close socket
    close(client_fd);
    return 0;
}

2.2 client_UDP.c

#include <my_head.h>

#definePORT 6666
#define IP "192.168.125.103"

int main(int argc, const char *argv[])
{<!-- -->
    //Create a report socket
    int server_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_fd < 0)
    {<!-- -->
        ERR_MSG("socket");
        return -1;
    }
    printf("Socket created successfully server_fd = %d\\
", server_fd);

    //Allow ports to be reused quickly
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, & amp;reuse, sizeof(reuse)) < 0)
    {<!-- -->
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("Allow port fast reuse successfully\\
");

    //The address information of the binding server must be bound
    struct sockaddr_in server_in; // Information used to bind this host
    server_in.sin_family = AF_INET; // AF_INET is required
                                               // Because the report socket was created earlier using IPv4
    server_in.sin_port = htons(PORT); //Specify port number
    server_in.sin_addr.s_addr = inet_addr(IP); // Bind local IP
    // Binding
    if (bind(server_fd, (struct sockaddr *) & amp;server_in, sizeof(server_in)) < 0)
    {<!-- -->
        ERR_MSG("bind");
        return -1;
    }
    printf("bind successful\\
");

    // UDP does not require a connection, so there is no need to listen.

    //  Receive data
    char buff[128];
    ssize_t res = 0;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    while (1)
    {<!-- -->
        // Clear the temporary storage area
        bzero(buff, sizeof(buff));
        // Receive data When the last parameter is 0, you can also use read
        // res = recv(new_fd, buff, sizeof(buff), 0);
        // res = read(server_fd, buff, sizeof(buff));
        res = recvfrom(server_fd, buff, sizeof(buff), 0, (struct sockaddr *) & amp;client_addr, & amp;client_len);
        if (res < 0)
        {<!-- -->
            ERR_MSG("recvfrom");
            return -1;
        }

        // Output client information and received data
        printf("[ %s : %d ] [massage : %s ]\\
", inet_ntoa(client_addr.sin_addr),
               htons(client_addr.sin_port), buff);

        //The data received is exit (exit)
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }

        //  send data
        //Send message to client
        printf("reply:");
        scanf("%s", buff);
        if (!strcmp(buff, "exit"))
        {<!-- -->
            printf("Disconnected\\
");
            break;
        }
        //  send
        if (sendto(server_fd, buff, sizeof(buff), 0, (struct sockaddr *) & amp;client_addr, client_len) < 0)
        {<!-- -->
            ERR_MSG("sendto");
            return -1;
        }
        printf("buff = %s\\
", buff);
        putchar(10);
    }

    //Close socket
    close(server_fd);
    return 0;
}