读取客户端响应导致服务器崩溃
Reading client response crashes server
我正在编写一个程序,其中服务器由另一个程序发出信号,在收到信号后,它从共享内存段读取目录名称并通过 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();
}
}
此外,这是我在主函数中接受连接的方式
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;
}
首先,正如马丁·詹姆斯所说,
printf("\n%s\n", (char*)client_message);
需要以 NUL 结尾的字符串。这不是由您的服务器代码强制执行的,如果您从
等客户端发送以 NUL 结尾的字符串
write(fd, str, strlen(str));
那么你就不会发送'[=13=]'
(你需要发送strlen(str) + 1
字节或者在接收端添加'[=13=]'
注意不要溢出你的缓冲区1字节)。
其次,我对signal-safe/unsafe代码的编写不熟悉,所以无法对此发表评论,但这里也可能存在问题。
主要问题
恕我直言,您的代码的主要问题是您声明了一个未初始化的字符串指针数组 cli_dir
,然后将此类指针传递给 strcpy
:
strcpy(cli_dir[i],(char*)client_message);
如果我的代码正确,这里你传递了一个指向内存位置的指针,strcpy
必须将字符串复制到该位置,但你没有以某种方式为副本分配内存,cli_dir[i]
现在包含一些任意垃圾。这很可能会导致分段错误。
我正在编写一个程序,其中服务器由另一个程序发出信号,在收到信号后,它从共享内存段读取目录名称并通过 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();
}
}
此外,这是我在主函数中接受连接的方式
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;
}
首先,正如马丁·詹姆斯所说,
printf("\n%s\n", (char*)client_message);
需要以 NUL 结尾的字符串。这不是由您的服务器代码强制执行的,如果您从
等客户端发送以 NUL 结尾的字符串write(fd, str, strlen(str));
那么你就不会发送'[=13=]'
(你需要发送strlen(str) + 1
字节或者在接收端添加'[=13=]'
注意不要溢出你的缓冲区1字节)。
其次,我对signal-safe/unsafe代码的编写不熟悉,所以无法对此发表评论,但这里也可能存在问题。
主要问题
恕我直言,您的代码的主要问题是您声明了一个未初始化的字符串指针数组 cli_dir
,然后将此类指针传递给 strcpy
:
strcpy(cli_dir[i],(char*)client_message);
如果我的代码正确,这里你传递了一个指向内存位置的指针,strcpy
必须将字符串复制到该位置,但你没有以某种方式为副本分配内存,cli_dir[i]
现在包含一些任意垃圾。这很可能会导致分段错误。