用select的时候 设置超时时间 就有一些数据收不到,当设置为轮询就可以啦。

这不科学啊!为毛?

#include <winsock.h>
#include <stdio.h>

#include <string>

#pragma comment(lib, "ws2_32.lib")

#define MYPORT 1234    // the port users will be connecting to
#define BACKLOG 5     // how many pending connections queue will hold
#define BUF_SIZE 200
int fd_A[BACKLOG];    // accepted connection fd
int conn_amount;    // current connection amount

void showclient()
{

    int i;

    printf("client amount: %d\n", conn_amount);

    for (i = 0; i < BACKLOG; i++) {

    printf("[%d]:%d  ", i, fd_A[i]);
    }
    printf("\n\n");

}

int main(void)
{
    WSADATA     wsaData;
    WSAStartup(0x0202, &wsaData);
    int sock_fd, new_fd;  // listen on sock_fd, new connection on new_fd

    struct sockaddr_in server_addr;    // server address information
    struct sockaddr_in client_addr; // connector's address information
    int sin_size;
    int yes = 1;
    char buf[BUF_SIZE];
    int ret;
    int i;


    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

        perror("socket");
        exit(1);
    }

    //if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, NULL, sizeof(int)) == -1) {
    //    perror("setsockopt");
    //    exit(1);
    //}

    server_addr.sin_family = AF_INET;         // host byte order
    server_addr.sin_port = htons(MYPORT);     // short, network byte order
    server_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));

    if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(sock_fd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    printf("listen port %d\n", MYPORT);

    fd_set fdsr;
    int maxsock;
    struct timeval tv;
    conn_amount = 0;
    sin_size = sizeof(client_addr);
    maxsock = sock_fd;

    while (1) {
        // initialize file descriptor set

        FD_ZERO(&fdsr);

        FD_SET(sock_fd, &fdsr);
        // timeout setting

        tv.tv_sec = 0;

        tv.tv_usec = 0;
        // add active connection to fd set

        for (i = 0; i < BACKLOG; i++) {

            if (fd_A[i] != 0) {

                FD_SET(fd_A[i], &fdsr);
            }
        }

        ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);

        if (ret < 0) {

            perror("select");

            break;

        } /*else if (ret == 0) {

            printf("timeout\n");

            continue;

        }*/

        // check every fd in the set

        for (i = 0; i < conn_amount; i++) 
        {

            if (FD_ISSET(fd_A[i], &fdsr)) 
            {

                ret = recv(fd_A[i], buf, sizeof(buf), 0);

                if (ret <= 0) {        // client close

                    printf("client[%d] close\n", i);

                    closesocket(fd_A[i]);

                    FD_CLR(fd_A[i], &fdsr);

                    fd_A[i] = 0;

                } else 
                {        // receive data

                    if (ret < BUF_SIZE)

                        memset(&buf[ret], '\0', 1);

                    printf("client[%d] send:%s\n", i, buf);

                }

            }

        }



        // check whether a new connection comes

        if (FD_ISSET(sock_fd, &fdsr)) 
        {

            new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);

            if (new_fd <= 0) 
            {

                perror("accept");

                continue;

            }



            // add to fd queue

            if (conn_amount < BACKLOG) 
            {

                fd_A[conn_amount++] = new_fd;

                printf("new connection client[%d] %s:%d\n", conn_amount,

                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

                if (new_fd > maxsock)

                    maxsock = new_fd;

            }

            else 
            {

                printf("max connections arrive, exit\n");

                send(new_fd, "bye", 4, 0);

                closesocket(new_fd);

                break;

            }

        }

        //showclient();

    }



    // close other connections

    for (i = 0; i < BACKLOG; i++) 
    {
        if (fd_A[i] != 0) {

            closesocket(fd_A[i]);
        }

    }
    exit(0);

}
View Code

相关文章: