Simple implementation of Linux multi process CS server

Keywords: Linux socket network

Simple implementation of Linux multi process CS server

server side

  • Multi process realizes multi-user connection, i.e. one connection for each user. Here, the server is still used to capitalize the received string and return it to the client.
    • code implementation
    #include <stdio.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    
    #define SERV_IP "127.0.0.1"
    #define SERV_PORT 8000
    
    void wait_child(int signo)
    {
        while(waitpid(0, NULL, WNOHANG)>0);
        return;
    }
    int main(int argc,char *argv[])
    {
        pid_t pid;//Process ID
        int sfd, cfd;//Receive the connected sfd and the cfd communicating with the client
        struct sockaddr_in serv_addr, clie_addr;//Create server and client structures
        socklen_t clie_addr_len;//Client structure length
        char buf[BUFSIZ], clie_IP[BUFSIZ];//buf stores received data
        int n , i;//Number of data read n, cycle factor i
    
        sfd = Socket(AF_INET, SOCK_STREAM, 0);//Create socket
    
        bzero(&serv_addr, sizeof(serv_addr));//Zero clearing
        serv_addr.sin_family = AF_INET;//Set protocol family to IPv4
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //Set the network card to any valid local network card
        //inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);
        serv_addr.sin_port = htons(SERV_PORT);//Set port
    
        bind(sfd, (struct sockaddr * )&serv_addr, sizeof(serv_addr));//Set socket to associate with sfd
        listen(sfd, 128);//Set the maximum number of incomplete accept. Start listening
        while(1)//Loop receive client connection
        {
            clie_addr_len = sizeof(clie_addr);//Initialize client structure length
            cfd = accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len);//Receive client connection
            printf("client IP:%s, port:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port));
            pid = fork();//Create a new process
            if(pid< 0)//error
            {
                perror("fork error");
                exit(1);
            }
            else if(pid == 0)//Subprocess
            {
                close(sfd);//Close parent process file descriptor first in child process
                break;
            }
            else if(pid>0)//Parent process
            {
                close(cfd);//Close child process file descriptor first in parent process
                signal(SIGCHLD, wait_child);
            }
        }
        if(pid == 0)//Here is the real business processing part of the subprocess
        {
            while(1)//Loop client business
            {
                n = read(cfd, buf, sizeof(buf));
                if(n == 0)//If read returns 0, the client is disconnected
                {  
                    close(cfd);//Close client file descriptor
                    return 0;
                }
                else if(n == -1)//error
                {
                    perror("read error");
                    exit(1);
                }
                else
                {
                    write(STDOUT_FILENO, buf, n);
                    for(i= 0; i< n;++i)
                    {
                        buf[i] = toupper(buf[i]);
                    }
                    write(cfd, buf, n);
                }
            }
        }
        return 0;
    }
    

client side

  • Connect to the server side, send the string, and print the received string (that is, it has the same function as the nc command).
    • code implementation
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #define MAXLINE 8192
    #define SERV_PORT 8000
    
    int main(int argc,char *argv[])
    {
        struct sockaddr_in servaddr;
        char buf[MAXLINE];
        int sockfd, n;
    
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
    
        servaddr.sin_family = AF_INET;
        inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
        servaddr.sin_port = htons(SERV_PORT);
    
        connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
        while(fgets(buf, MAXLINE, stdin)!=NULL)
        {
            write(sockfd, buf, strlen(buf));
            n =Read(sockfd, buf, MAXLINE);
            if(n ==0)
            {
                printf("the other side has been closed.\n");
                break;
            }
            else 
                write(STDOUT_FILENO, buf, n);
        }
        close(sockfd);
        return 0;
    }
    

test result

  • Multiple clients can connect to the server at the same time. Each time the server accepts a client, it creates a child process. After the client is disconnected, the child process is automatically recycled by the parent process.

Problems

  • Without error handling, interference may occur when multiple users connect.

Posted by allinurl on Sun, 03 May 2020 14:00:54 -0700