代码之家  ›  专栏  ›  技术社区  ›  OntologicalSin

读取客户端响应使服务器崩溃

  •  1
  • OntologicalSin  · 技术社区  · 7 年前

    该程序适用于所有其他情况,例如客户端连接、不发送任何内容,然后断开连接。

    void handler(int signal_number)
    {   
        int read_size;
        char* cli_dir[1000];
        char *message , client_message[2000];
        int i = 0;
    
        printf("about to access shared memory");
        message = shm; //shm is the directory name in shared memory
        puts("accessed shared memory");
        printf("is gonna be sent to client %s\n",message);
        write(sock , (char*)message , strlen(message));
    
        while((read_size = recv(sock , client_message , 2000 , 0)) > 0 )
        {
            //read client response and log contents of the received directory
            printf("\n%s\n", (char*)client_message);
            strcpy(cli_dir[i],(char*)client_message);
            i++;
            printf("\n");
            perror("error here");
        }
    
        if(read_size == 0)
        {
            puts("Client disconnected");
            fflush(stdout);
            perror("error 2 here"); 
        }
        else if(read_size == -1)
        {
            perror("receiving server side failed");
        }
    }
    
    void* connection_handler(void *socket_desc)
    {
        //Get the socket descriptor
        printf("accessed connection handler");
    
        sock = *(int*)socket_desc;
    
        while(1){
    
            signal(SIGUSR1, handler);
    
            // struct sigaction sa;
            // printf("signal recieved");
            // memset(&sa, 0, sizeof(sa)); //alternative signal handler
            // sa.sa_handler = &handler;
            // sigaction(SIGUSR1, &sa, NULL);
    
            pause();
        }
    }
    

    此外,以下是我如何在主函数中接受连接

        while( (client_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
        {
            puts("Client accepted");
    
            pthread_t sniff;
            new_sock = malloc(1);
            *new_sock = client_sock;
    
            if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
            {
                perror("could not create thread");
                return 1;
            }
    
            pthread_join( sniff , NULL);
            puts("client handled");
        }
    
        if (client_socket < 0)
        {
            perror("accept failed");
            return 1;
        }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Anatoly Trosinenko    7 年前

    首先,正如马丁·詹姆斯所说,

    printf("\n%s\n", (char*)client_message);
    

    需要以NUL结尾的字符串。这不是由服务器代码强制执行的,如果您从类似

    write(fd, str, strlen(str));
    

    那么您将不会发送 '\0' (您需要发送 strlen(str) + 1 在接收端,小心不要使缓冲区溢出1字节)。

    其次,我不熟悉编写信号安全/不安全代码,因此无法对此发表评论,但这里可能也有问题。

    主要问题

    cli_dir 然后将该指针传递给 strcpy :

    strcpy(cli_dir[i],(char*)client_message);
    

    拷贝字符串 必须复制一个字符串,但您没有为复制和 cli_dir[i] 现在包含一些任意垃圾。这很可能会导致分割错误。