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


服务端初始化:

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);
}
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值