Linux多进程CS服务器简单实现

Posted yanlei2018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux多进程CS服务器简单实现相关的知识,希望对你有一定的参考价值。

Linux多进程CS服务器简单实现

server端

  • 多进程实现多用户连接,即每个用户一个连接,这里仍然用server将收到的字符串转大写后返回给客户端。
    • 代码实现
    #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;//进程ID
        int sfd, cfd;//接收连接的sfd,和client通讯的cfd
        struct sockaddr_in serv_addr, clie_addr;//创建服务器和客户端结构体
        socklen_t clie_addr_len;//客户端结构体长度
        char buf[BUFSIZ], clie_IP[BUFSIZ];//buf存放接收到的数据
        int n , i;//读取的数据数n, 循环因子i
    
        sfd = Socket(AF_INET, SOCK_STREAM, 0);//创建套接字
    
        bzero(&serv_addr, sizeof(serv_addr));//清零
        serv_addr.sin_family = AF_INET;//设置协议族为IPv4
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //设置网卡为本地任何有效网卡
        //inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);
        serv_addr.sin_port = htons(SERV_PORT);//设置端口
    
        bind(sfd, (struct sockaddr * )&serv_addr, sizeof(serv_addr));//设置套接字与sfd关联
        listen(sfd, 128);//设置未完成accept的最大数量.开始监听.
        while(1)//循环接收客户端连接
        {
            clie_addr_len = sizeof(clie_addr);//初始化客户端结构体长度
            cfd = accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len);//接收客户端连接
            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();//创建新进程
            if(pid< 0)//出错
            {
                perror("fork error");
                exit(1);
            }
            else if(pid == 0)//子进程
            {
                close(sfd);//子进程中先关闭父进程文件描述符
                break;
            }
            else if(pid>0)//父进程
            {
                close(cfd);//父进程中先关闭子进程文件描述符
                signal(SIGCHLD, wait_child);
            }
        }
        if(pid == 0)//以下是子进程真正的业务处理部分
        {
            while(1)//循环处理客户端业务
            {
                n = read(cfd, buf, sizeof(buf));
                if(n == 0)//如果read返回0, 说明客户端已断开连接
                {  
                    close(cfd);//关闭客户端文件描述符
                    return 0;
                }
                else if(n == -1)//出错
                {
                    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端

  • 连接server端,发送字符串,将受到的字符串打印出来(即:与nc命令功能相同)。
    • 代码实现
    #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;
    }
    

测试结果

  • 可以实现多个客户端同时连接服务器,服务器每接受一个客户就创建一个子进程,用户端断开后,进程由父进程自动回收子进程。

存在问题

  • 未进行错误处理,多用户连接时,可能会产生干扰。

以上是关于Linux多进程CS服务器简单实现的主要内容,如果未能解决你的问题,请参考以下文章

Linux下实现PHP多进程的方法分享

代码片段:Shell脚本实现重复执行和多进程

Linux C实现简单,多进程,多线程服务器

c++ 网络编程TCP/IP linux 下多进程socket通信 多个客户端与单个服务端交互代码实现回声服务器

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

LINUX操作系统知识:进程与线程详解