C/Unix 套接字 : Server closes right after one client does

标签 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 ,但这只会在服务器上造成无限循环。

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

最佳答案

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

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

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

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

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

关于C/Unix 套接字 : Server closes right after one client does,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44085664/

相关文章:

java - 多进程监听端口时,tomcat为什么会收到请求?

c# - 检查客户端是否正在尝试连接?

c - 从 .txt 文件中读取随机行

c - 如何使用C程序检测文件中的特定字符串

c - 如何读取文件行(整​​数)并对从 A 行到 B 行的总数求和?

c# - 在 form.show 之后让主线程在按下按钮时执行代码

java - 如何停止 BufferedReader readline()?

java - 如何从多线程返回值?

c++ - 处理 POSIX 套接字 read() 错误

无法打印变量的 scanf_s 值的 ASCII 值