Linux网络编程9 -- 简单总结Select改善多进程并发服务器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YZC1078/article/details/78491121

一、多进程处理方式
这里写图片描述

在生成连接套接字的同时创建新的进程,用于处理该套接字的相应操作。
原进程继续连接生成新的套接字,从而相互不影响,并发执行。

pid_t pid;
while (1)
{
    if ((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0)
        ERR_EXIT("accept");

    printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));

    pid = fork();
    if (pid == -1)
        ERR_EXIT("fork");
    if (pid == 0)
    {
        close(listenfd);
        echo_srv(conn);
        exit(EXIT_SUCCESS);
    }
    else
        close(conn);
}

二、select处理单进程并发服务器

这里写图片描述

轮询select函数,监听多个套接字,判断响应事件的套接字,并做出相应的处理。

int i;
int client[FD_SETSIZE];
int maxi = 0;

for (i=0; i<FD_SETSIZE; i++)
    client[i] = -1;

int nready;
int maxfd = listenfd;
fd_set rset;
fd_set allset;
FD_ZERO(&rset);
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
while (1)
{
    rset = allset;
    nready = select(maxfd+1, &rset, NULL, NULL, NULL);
    if (nready == -1)
    {
        if (errno == EINTR)
            continue;

        ERR_EXIT("select");
    }
    if (nready == 0)
        continue;

    if (FD_ISSET(listenfd, &rset))
    {
        peerlen = sizeof(peeraddr);
        conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen);
        if (conn == -1)
            ERR_EXIT("accept");

        for (i=0; i<FD_SETSIZE; i++)
        {
            if (client[i] < 0)
            {
                client[i] = conn;
                if (i > maxi)
                    maxi = i;
                break;
            }
        }

        if (i == FD_SETSIZE)
        {
            fprintf(stderr, "too many clients\n");
            exit(EXIT_FAILURE);
        }
        printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));

        FD_SET(conn, &allset);
        if (conn > maxfd)
            maxfd = conn;

        if (--nready <= 0)
            continue;

    }

    for (i=0; i<=maxi; i++)
    {
        conn = client[i];
        if (conn == -1)
            continue;

        if (FD_ISSET(conn, &rset))
        {
            char recvbuf[1024] = {0};
            int ret = readline(conn, recvbuf, 1024);
                    if (ret == -1)
                            ERR_EXIT("readline");
                    if (ret == 0)
                    {
                            printf("client close\n");
                FD_CLR(conn, &allset);
                client[i] = -1;
                    }

                    fputs(recvbuf, stdout);
                    writen(conn, recvbuf, strlen(recvbuf));

            if (--nready <= 0)
                break;

        }
    }
}    

代码来自摘自Linux网络编程。

猜你喜欢

转载自blog.csdn.net/YZC1078/article/details/78491121