Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2244009
  • 博文数量: 395
  • 博客积分: 10994
  • 博客等级: 上将
  • 技术积分: 5586
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 19:49
文章存档

2014年(1)

2013年(10)

2012年(74)

2011年(303)

2010年(7)

分类: LINUX

2011-10-10 14:42:54

下面是我转帖的一片百度知道的帖子,对selectsokect的执行流程说的比较不错的。。 


以下是《linux C编程一站式学习》的最后一章的一段select函数代码,

浏览次数:70悬赏分:0 | 解决时间:2011-5-26 13:23 | 提问者:

注释已经写的非常清楚,但是还是不知道这个程序的具体执行流程,太抽象了,求详细讲解,必重谢!

/* server.c */

#include 

#include 

#include 

#include 

#include "wrap.h"

#define MAXLINE 80

#define SERV_PORT 8000

int main(int argc, char **argv)

{

    int i, maxi, maxfd, listenfd, connfd, sockfd;

    int nready, client[FD_SETSIZE];

    ssize_t n;

    fd_set rset, allset;

    char buf[MAXLINE];

    char str[INET_ADDRSTRLEN];

    socklen_t cliaddr_len;

    struct sockaddr_in  cliaddr, servaddr;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);

    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, (struct sockaddr *)&servaddr, sizeof(servaddr));

    Listen(listenfd, 20);

    maxfd = listenfd;       /* initialize */

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

    for (i = 0; i < FD_SETSIZE; i++)

        client[i] = -1; /* -1 indicates available entry */

    FD_ZERO(&allset);

    FD_SET(listenfd, &allset);

    for ( ; ; ) {

        rset = allset;  /* structure assignment */

        nready = select(maxfd+1, &rset, NULL, NULL, NULL);

        if (nready < 0)

            perr_exit("select error");

        if (FD_ISSET(listenfd, &rset)) { /* new client connection */

            cliaddr_len = sizeof(cliaddr);

            connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);

            printf("received from %s at PORT %d\n",

                   inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),

                   ntohs(cliaddr.sin_port));

            for (i = 0; i < FD_SETSIZE; i++)

                if (client[i] < 0) {

                    client[i] = connfd; /* save descriptor */

                    break;

                }

            if (i == FD_SETSIZE) {

                fputs("too many clients\n", stderr);

                exit(1);

            }

            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)) {

                if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {

                    /* connection closed by client */

                    Close(sockfd);

                    FD_CLR(sockfd, &allset);

                    client[i] = -1;

                } else {

                    int j;

                    for (j = 0; j < n; j++)

                        buf[j] = toupper(buf[j]);

                    Write(sockfd, buf, n);

                }

                if (--nready == 0)

                    break;  /* no more readable descriptors */

            }

        }

    }

}

最佳答案

大体是这样子的:

首先用一个用socekt进行监听(listenfdSERV_PORT端口。

然后把listenfd放到 集合里。

在循环里用select轮询,当集合里有可读的socket时,select返回。

select返回后,判断是否是listenfd可读,如果是,那么就有新的客户端连进来,进行

接收(accept)。accept到的connfd保存到客户端列表里(client[n]),然后同样加

到集合里,以便进行下一次轮询。

如果不是listenfd可读,那么遍历所有客户端socket,检查是否可读,如果可读,就读取

数据,转换成大写然后发送回客户端。如果客户端断开,那么从client列表和集合里去除掉。 

不过,居然是0分呀 -_-!

阅读(1299) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~