您的位置:首页 > 理论基础 > 计算机网络

select实现tcp并发服务器的基本框架流程

2013-11-18 15:11 681 查看
服务端初始化:

socket();

bind();

listen();

for( ; ; )   

{

        FD_SET(listen_fd , &allset);//设置监听读写文件描述符

        select();//调用select函数

        if()//如果是倾听套接字就绪,说明一个新的连接请求建立

        {

                建立连接(accept);

                加入到监听文件描述符中去;

        }

        else//否则说明是一个已经连接过的描述符

        {

                进行操作(read或者write);

        }

}

#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/socket.h>

#include <errno.h>

#include <strings.h>

#include <arpa/inet.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/select.h>

#include <sys/time.h>

#include <pthread.h>

#define SERV_PORT 9888

#define WAIT_COUNT 5

#define READ_SIZE 32

//void send_myself(int fd);

//void *pthread_handle(void *arg);

int main(int argc, char **argv)



        pthread_t tid;

        

        int i,max_i,listen_fd,max_fd,conn_fd,sock_fd;

        int nready,client[FD_SETSIZE];

        fd_set allset;

        struct sockaddr_in  listen_addr,client_addr;

        socklen_t len = sizeof(struct sockaddr_in);
listen_fd = socket(PF_INET,SOCK_STREAM,0);
if(listen_fd == -1)
{
perror("socket failed !");
return -1;
}

        max_i = -1;

        max_fd = listen_fd;

bzero(&listen_addr,sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(SERV_PORT);
bind(listen_fd,(struct sockaddr *)&listen_addr,len);
listen(listen_fd,WAIT_COUNT);

    

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

    

        for(;;)

        {
   FD_SET(listen_fd,&allset);

            

            nready = select(max_fd+1,&allset,NULL,NULL,NULL);

            if(FD_ISSET(listen_fd,&allset))

            {

                len = sizeof(struct sockaddr);
       conn_fd = accept(listen_fd,(struct sockaddr *)&listen_addr,&len);
       if(conn_fd == -1)

                {

                    perror("accept fail !");

                    return -1;

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

                {
           if(client[i] < 0)
           {
               client[i] = conn_fd;
       break;
           }
       }

       if(FD_SETSIZE == i)
       {
           perror("too many clients!");
           return -1;
       }

       FD_SET(conn_fd,&allset);/*add new descriptor to allset*/

       if(conn_fd > max_fd)
           max_fd = conn_fd;
       if(i > max_i)
           max_i = i;

                if(--nready <= 0)

                    continue;

            }

            else

            { 

            for(i = 0; i <= max_i; ++i)/*check all clients for data*/

            {

                if((sock_fd = client[i]) < 0)
           continue;

       if(FD_ISSET(sock_fd,&allset))
       {

                    //int *lptr = (int*)malloc(sizeof(int));

                    //*lptr = sock_fd;
           //int err = pthread_create(&tid,NULL,pthread_handle,lptr);

                    //send_myself(sock_fd);

                    char tmp[READ_SIZE] = {0};

                    int size = read(sock_fd,tmp,READ_SIZE-1);

                    write(STDOUT_FILENO,tmp,size);

                    bzero(tmp,READ_SIZE);

                    

                    FD_CLR(sock_fd,&allset);

                    close(sock_fd);

                    client[i] = -1;

               

                    continue;

                    

                    //if(--nready <= 0)

                        //break; 
       }

            }

            }

    }

    return 0;

}

/*

void *pthread_handle(void *arg)

{

    int connfd = *((int*)arg);

    free(arg);

    pthread_detach(pthread_self());

    send_myself(connfd);

    close(connfd);

    return NULL;

}

*/

/*

void send_myself(int fd)

{
char tmp[READ_SIZE] = {0};
char *p_tmp = tmp;
while(1)
{
int size = read(fd, tmp,READ_SIZE-1);
write(STDOUT_FILENO,tmp,size);
if(0 == size)
{
perror("read fail!");
return;
}
if(0 == write(fd,tmp,size))
{
perror("write client failed !");
return;
}
bzero(tmp,READ_SIZE);
}

}

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  select tcp 并发 服务器