C / Unix套接字:服务器在一个客户端之后立即关闭

时间:2017-05-20 12:07:21

标签: c multithreading sockets

(这个问题是this可怕问题的续集)

我已经设法用我破碎的代码解决问题并使用线程为多个客户端工作。

服务器:

#define SOCK_PATH "avg_socket"

int numofclients=0;
int numofrequests=0;
pthread_mutex_t MUT=PTHREAD_MUTEX_INITIALIZER;

void *find_average (void *arg)
{
        int so = (int) arg;
        int done;

        printf("Connected.\n");

            done = 0;

            do {
                int i=0;
                int numofelements=0;
                int sum=0;
                float avg;

               ...
               ...
               ...


                pthread_mutex_lock(&MUT);
                        numofrequests++;
                pthread_mutex_unlock(&MUT);

                printf("\n\nNumber of requests: %d \n", numofrequests);
                printf("Number of clients: %d \n", numofclients);    

            } while (!done);

         close(so);
         pthread_exit(NULL);
}

int main(void)
    {
        int s, s2, i, t, len;
        struct sockaddr_un local, remote;
        pthread_t thread[50];

        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }

        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, SOCK_PATH);
        unlink(local.sun_path);
        len = strlen(local.sun_path) + sizeof(local.sun_family);
        if (bind(s, (struct sockaddr *)&local, len) == -1) {
            perror("bind");
            exit(1);
        }

        if (listen(s, 5) == -1) {
            perror("listen");
            exit(1);
        }

        i=0;

        for(;;) {
            printf("Waiting for a connection...\n");
            t = sizeof(remote);
            if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
                perror("accept");
                exit(1);
            }
            numofclients++; //counting the number of clients
            pthread_create(&(thread[i++]), NULL, find_average, (void *)s2);
         }

        return 0;
    }

客户端:

#define SOCK_PATH "avg_socket"

    int main(void)
    {
        int i, s, t, len, done;

        struct sockaddr_un remote;

        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }

        printf("Trying to connect...\n");

        remote.sun_family = AF_UNIX;
        strcpy(remote.sun_path, SOCK_PATH);
        len = strlen(remote.sun_path) + sizeof(remote.sun_family);
        if (connect(s, (struct sockaddr *)&remote, len) == -1) {
            perror("connect");
            exit(1);
        }

        printf("Connected.\n");

        done = 0;
        int yesorno=1;

        do {
            float avg;
            char seq[100];
            char str[100];
            char avgstring[200];


            printf("Give the sequence of integers: \n");
            fgets(seq, 100, stdin);

            ...
            ...
            ...

            printf("\nWanna Continue? (1/0) :");
            scanf("%d", &yesorno);
            getchar();

            if(!yesorno)
                done=1;

         } while (!done);

        close(s);

        return 0;
    }

(感兴趣的任何人的完整代码here

但是现在,每次我关闭一个客户端的连接时,服务器也会关闭。

enter image description here

如上所示,客户端3关闭与服务器的连接,服务器本身同时关闭,而不是等待连接或客户端请求。

对我来说,似乎服务器上有close(so)的内容。我试图将它移动到循环内部here,但这只是在服务器上进行了无限循环。

所以问题是,当客户端关闭时,如何保持多线程服务器处于活动状态?

1 个答案:

答案 0 :(得分:1)

            char arr[100];
            recv(so, arr, 100, 0);

            int *array;    
            array=(int *)calloc(1, 100);

            char *p=strtok(arr, " ");

strtok函数需要一个字符串作为其第一个参数。通过网络连接接收的任意字节集合不是字符串。

在相关问题中,您会丢弃recv的结果。所以你无法知道你什么时候失败了。更糟糕的是,如果你成功了,你不知道你收到了多少字节!你期望strtok如何知道?魔法?