tcp服务器(使用select)

//修改于《UNIX网络编程》

#include <stdlib.h>

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>


#define MAXLINE         128
#define SERV_PORT       8001
#define LISTENQ         100
#define MAX_CLIENT_NUM  100
typedef struct sockaddr SA;


int main(int argc, char **argv)
{
    int i, maxi, maxfd, listenfd, connfd, sockfd;
    int nready, client[MAX_CLIENT_NUM];
    ssize_t n;
    fd_set rset, allset;
    char buf[MAXLINE];
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;
    int Option = 1, nNum = 0;


    listenfd = socket(AF_INET, SOCK_STREAM, 0);


    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &Option, sizeof(Option)) < 0)
    {
        return -1;
    }


    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);


    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));


    listen(listenfd, LISTENQ);


    maxfd = listenfd; /* initialize */
    maxi = -1; /* index into client[] array */


    for (i = 0; i < MAX_CLIENT_NUM; i++)
    {
        client[i] = -1; /* -1 indicates available entry */
    }


    FD_ZERO(&allset);
    FD_SET(listenfd, &allset);


    while (1)
    {
        rset = allset; /* structure assignment */
        nready = select(maxfd + 1, &rset, NULL, NULL, NULL);


        if (FD_ISSET(listenfd, &rset))   /* new client connection */
        {
            clilen = sizeof(cliaddr);
            connfd = accept(listenfd, (SA *) &cliaddr, &clilen);


            printf("new client: %s, port %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));


            for (i = 0; i < MAX_CLIENT_NUM; i++)
            {
                if (client[i] < 0)
                {
                    client[i] = connfd; /* save descriptor */
                    break;
                }
            }


            if (i == MAX_CLIENT_NUM)
            {
                printf("too many clients\r\n");
                //continue;
                close(client[i - 1]);
                FD_CLR(client[i - 1], &allset);
                client[i - 1] = connfd;
            }


            FD_SET(connfd, &allset); /* add new descriptor to set */
            if (connfd > maxfd)
            {
                maxfd = connfd; /* for select */
            }


            if (i > maxi)
            {
                maxi = i; /* max index in client[] array */
            }


            if (--nready <= 0)
            {
                continue; /* no more readable descriptors */
            }
        }


        for (i = 0; i <= maxi; i++)
        {
            /* check all clients for data */
            if ((sockfd = client[i]) < 0)
            {
                continue;
            }


            if (FD_ISSET(sockfd, &rset))
            {
                memset(buf, 0, MAXLINE);
                if (((n = read(sockfd, buf, MAXLINE)) == 0) || (buf[0] == 0x03))
                {
                    /*4connection closed by client */
                    close(sockfd);
                    FD_CLR(sockfd, &allset);
                    client[i] = -1;
                }
                else
                {
                    printf("read %d bytes:%s\n", n, buf);
                }


                if (--nready <= 0)
                {
                    break; /* no more readable descriptors */
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值