服务器 - 客户端线程接受错误/泄漏

时间:2013-10-18 02:15:36

标签: c client-server semaphore

运行server.c代码后,我一直收到“Accept:too many files”错误。试图让它为客户端创建新线程并限制与信号量的连接。

这是我的代码:

#define MAX_CLIENTS 30
sem_t s;

void *handle(void *pnewsock);

int sockfd, new_fd, numbytes;  // listen on sock_fd, new connection on new_fd
    struct sockaddr_in my_addr;    // my address information
    struct sockaddr_in their_addr; // connector's address information
    socklen_t sin_size;
    pthread_t thread;

int main(void){
    //initialise locks
    sem_init(&s, 0, 0);

    /* generate the socket */
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(true);
    }

    my_addr.sin_family = AF_INET;         // host byte order
    my_addr.sin_port = htons(MYPORT);     // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP

    /* bind the socket to the end point */
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
    == -1) {
            perror("bind");
            exit(true);
    }

    /* start listnening */
    if (listen(sockfd, BACKLOG) == -1) {
            perror("listen");
            exit(true);
    }
    printf("server starts listening ...\n");

    /* Main loop */
    while (1) {
            sin_size = sizeof(struct sockaddr_in);
            if (pthread_create(&thread, NULL, handle, &new_fd) != 0) {
                    fprintf(stderr, "Failed to create thread\n");
            }
    }
    return 0;
}

void *handle(void *pnewsock){
    int value;
    sem_getvalue(&s,&value);
    while (value >= MAX_CLIENTS){
            printf("too many connections");
            sem_wait(&s);
    }
    if (value < MAX_CLIENTS){
            if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
                    &sin_size)) == -1) {
                    perror("accept");
                    exit(1);
            }
            printf("server: got connection from %s\n", \
                    inet_ntoa(their_addr.sin_addr));

            char buffer[MAXDATASIZE];
            char res[MAXDATASIZE];

            memset(buffer, '\0', MAXDATASIZE);
            memset(res, '\0', sizeof(res));

            if ((numbytes=recv(new_fd, buffer, sizeof(buffer), 0)) == -1) {
                    perror("recv");
                    exit(true);
            }
            else if(numbytes == 0) {
                    printf("client left");
                    sem_post(&s);
                    close(new_fd);
                    exit(false);
            }
            else {
                    buffer[numbytes] = '\0'; // add null terminator
                    printf("Request: %s\n",buffer);
                    //search function
            }
    }
    close(new_fd);
    exit(false);
    return NULL;

}

有人能给我一些关于这个文件泄漏的见解吗?感谢

1 个答案:

答案 0 :(得分:0)

main()函数使用无限循环创建pthread。您的错误很可能与此相关,因为循环将继续创建更新的线程。

/* Main loop */
while (1) {
        sin_size = sizeof(struct sockaddr_in);
        if (pthread_create(&thread, NULL, handle, &new_fd) != 0) {
                fprintf(stderr, "Failed to create thread\n");
        }
}

您可能想要为每个客户创建一个线程。如果是这种情况,那么handle()函数应该在从accept()调用获得新客户端时调用pthread_create()。服务器(我们称之为侦听和接受的套接字)不需要多个线程 - 一个线程 - 可以是主线程 - 只需要它。