select服务器

来源:互联网 发布:淘宝商家如何删除差评 编辑:程序博客网 时间:2024/05/29 04:10

select服务器实现

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <sys/select.h>int fds_array[sizeof(fd_set)*8];static void usage(const char* proc){    printf("Usage: %s[local_ip] [local_port]\n", proc);}int startup(const char *_ip, int _port){    int sock = socket(AF_INET, SOCK_STREAM, 0);    if(sock < 0)    {        perror("socket");        return 3;    }    int opt = 1;    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));//解决server bind error的问题;    struct sockaddr_in local;    local.sin_family = AF_INET;    local.sin_port = htons(_port);    local.sin_addr.s_addr = inet_addr(_ip);    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)    {        perror("bind");        return 4;    }    if(listen(sock, 10) < 0)    {        perror("listen");        return 5;    }    return sock;}int main(int argc, char *argv[]){    if(argc != 3)    {        usage(argv[0]);        return 1;    }    int listen_sock = startup(argv[1], atoi(argv[2]));    int nums = sizeof(fds_array)/sizeof(fds_array[0]);    int i = 0;    for(;i < nums; i++)//将所有元素设置为无效    {        fds_array[i] = -1;    }    fds_array[0] = listen_sock; //将listen_sock加入到数组中;    while(1)    {        int max_fd = -1;        fd_set rfds;                //创建文件描述符集合        FD_ZERO(&rfds);             //将所有的元素清空        for(i = 0; i < nums; i++)        {            if(fds_array[i] == -1)            {                continue;            }            FD_SET(fds_array[i], &rfds);            if(fds_array[i] > max_fd)       //寻找select中第一个参数;                max_fd = fds_array[i];        }        struct timeval timeout = {5,0};        switch(select(max_fd+1, &rfds, NULL, NULL, /*&timeout*/NULL))        {            case -1:                {                    perror("select");                }                break;            case 0:                {                    printf("time out\n");                }                break;            default :                {                    for(i = 0; i < nums; ++i)                    {                        if(fds_array[i] < 0)                            continue;                        if(i == 0 && FD_ISSET(fds_array[i], &rfds))                        {                            struct sockaddr_in client;                            socklen_t len = sizeof(client);                            int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len);                            if(new_sock < 0)                            {                                perror("accept");                                continue;                            }                            printf("new client: [%s:%d]\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));                            int j = 1;                            for(; j < nums; j++)   //找到第一个无效的位置                            {                                if(fds_array[j] < 0)                                    break;                            }                            if(j == nums)                            {                                printf("server is full\n");                                close(new_sock);                                break;                            }                            else                            {                                fds_array[j] = new_sock;                            }                        }                        else if(i != 0 && FD_ISSET(fds_array[i], &rfds))                        {                            char buf[1024];                            ssize_t s = read(fds_array[i], buf, sizeof(buf)-1);                            if(s > 0)                            {                                buf[s] = 0;                                printf("client #:%s", buf);                            }                            else if(s == 0)                            {                                printf("client quit...\n");                                close(fds_array[i]);                                fds_array[i] = -1;                            }                            else                            {                                perror("read");                                close(fds_array[i]);                                return 7;                            }                        }                    }                }                break;        }    }    close(listen_sock);    return 0;}


原创粉丝点击