首页 文章

读取客户端响应会导致服务器崩溃

提问于
浏览
1

我正在编写一个程序,其中服务器由另一个程序发出信号,在收到信号后,它从共享内存段读取目录名称,并通过sock将其发送给客户端 . 客户端发送回目录的内容并断开连接

我的问题是,当服务器收到客户端响应时,它会打印它并立即停止侦听端口 .

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

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();
    }
}

另外,这是我如何接受main函数中的连接

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 回答

  • 2

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

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

    需要一个以NUL结尾的字符串 . 这不是由您的服务器代码强制的,如果您从客户端发送NUL终止的字符串,如

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

    然后你不会发送 '\0' (你需要发送 strlen(str) + 1 字节或在接收端添加 '\0' 小心不要将缓冲区溢出1个字节) .

    其次,我不熟悉编写信号安全/不安全代码,所以不能对此发表评论,但这里也可能存在问题 .

    主要问题

    恕我直言你的代码的主要问题是你声明一个未初始化的数组 cli_dir 指向字符串的指针,然后将这样的指针传递给 strcpy

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

    如果我得到你的代码,你在这里传递一个指向内存位置的指针, strcpy 必须复制一个字符串,但你没有以某种方式为副本分配内存, cli_dir[i] 现在包含一些任意垃圾 . 这很可能会导致分段错误 .

相关问题