我正在多线程环境中开发客户端 - 服务器应用程序。客户端和服务器都有两个线程。主线程使用套接字(IPv4-TCP)发送数据,客户端相应的主线程接收数据。发送和 recv 函数是作为我设计的一部分的自定义函数。我在另一个线程中为服务器上的 SIGUSR1、SIGUSR2 和 SIGINT 设置了三个信号处理程序。在接收 SIGINT 时,会进行线程清理以优雅地关闭所有套接字并终止线程,而在接收 SIGUSR1,SIGUSR2 时,我设置了两个全局标志,它们在同一线程中使用,并在主线程中自定义发送函数来做一些事情将套接字 id 切换为 IPv6 的操作。(有逻辑让客户端知道套接字已更改为 IPv6)。自定义发送/接收函数有 malloc 和 free 函数。
问题是当我在终端上使用 kill -SIGUSR1 pid 向服务器进程发送信号时,在一些发送调用之后,传输挂起。对于每个发送调用,我正在发送数据包,它具有要发送的数据大小、实际数据和一个可选标志,指示下一个数据将在另一个套接字 id 上。当我在客户端打印数据大小时,在收到信号后某些 recv 调用后它全部为零。我确信 SIGNAL 一定是原因,因为当我反转操作并让客户端将数据发送到服务器(上传)使用相同的发送/接收功能它工作正常。我能够切换套接字 ID。在这两种情况下,我都向服务器进程发送信号。recv 函数 recvs 直到数据量与该数据包的大小部分中指示的相同,因为 TCP 是基于流的。我不确定为什么在接收信号后进行一些发送调用后大小变为零。我使用了互斥锁,除了在设置信号处理程序部分时使用了全局变量。代码如下。
线程 2:
fn_sigUsrHandler(SIGUSR1);
fn_sigUsrHandler(SIGUSR2);
fn_sigUsrHandler(SIGINT);
void fn_sigUsrHandler(int p_signal)
{
/* Signal handler structure */
struct sigaction vl_sigStruct;
int vl_errno;
char vl_err_buff[256];
vl_sigStruct.sa_flags = SA_RESTART;
sigemptyset(&vl_sigStruct.sa_mask);
switch(p_signal)
{
case SIGUSR1:
vl_sigStruct.sa_handler = fn_switch;
break;
case SIGUSR2:
vl_sigStruct.sa_handler = fn_switch;
break;
case SIGINT:
vl_sigStruct.sa_handler = fn_cleanUP;
break;
}
vl_errno = sigaction(p_signal, &vl_sigStruct, NULL);
if (vl_errno == -1) {
fprintf(stdout,"Control Thread-Error in catching SIGUSR1:%s\n",fn_strerror_r(errno,vl_err_buff));
exit(EXIT_FAILURE);
}
void fn_switch(int st_val){
/*
pthread_mutex_lock(&socket_mutex_3);
ip_proto_switch = 1;
vg_ctrlpacket_sent =1;
pthread_mutex_unlock(&socket_mutex_3);
*/
vg_proto_switch = 1;
vg_ctrlpacket_sent =1;
fprintf(stdout,"Signalled to switch\n");
}
主线程:
int vl_err; /* Number of bytes sents */
char err_buff[256]; /* Buffer to hold error message*/
int vl_change_sock = 0;
if(p_flags != NO_DATA_TX)
{
char *vl_bufData;
st_packetData vst_packet; /* Structure holding the data to be sent */
unsigned int vl_packetSize = sizeof(unsigned int) + sizeof(vst_packet.vst_pad) + (int)p_len;//sss
vl_bufData = (char *)malloc(vl_packetSize);
memset(vl_bufData,'\0',vl_packetSize);
pthread_mutex_lock(&socket_mutex_2);
if(vg_ctrlpacket_recv == 1){
///strcpy(vst_packet.vst_pad,vg_change_socket);
vl_change_sock = 1;
vg_ctrlpacket_recv = 0;
fprintf(stdout,"len:%d\n",strlen(vst_packet.vst_pad));
}
pthread_mutex_unlock(&socket_mutex_2);
if(vl_change_sock == 1){
char *vl_bufData2 = vl_bufData+sizeof(unsigned int);
snprintf(vl_bufData2,(int)p_len,"%s",p_buffer);
//memcpy(vl_bufData+sizeof(unsigned int)+(int)p_len,vg_change_socket,sizeof(vst_packet.vst_pad));//sss
*/
snprintf(vl_bufData,sizeof(unsigned int)+1,"%u",vl_packetSize);
memcpy(vl_bufData+sizeof(unsigned int),p_buffer,(int)p_len);//sss
snprintf(vl_bufData+sizeof(unsigned int)+(int)p_len,sizeof(vst_packet.vst_pad)+1,"%s",vg_change_socket);
vl_err = send(p_mysocket->socket_id,vl_bufData,vl_packetSize,p_flags);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
if(debug > 0)
fprintf(stdout,"The socket before change is :%d client side \n",p_mysocket->socket_id);
if((p_mysocket->socket_id) == p_mysocket->sock_id[0])
p_mysocket->socket_id = p_mysocket->sock_id[1];
else
p_mysocket->socket_id = p_mysocket->sock_id[0];
if(debug > 0)
fprintf(stdout,"The socket after change is :%d client side \n ",p_mysocket->socket_id);
}
else{
snprintf(vl_bufData,sizeof(unsigned int)+1,"%u",vl_packetSize);
memcpy(vl_bufData+sizeof(unsigned int),p_buffer,(int)p_len);//sss
vl_err = send(p_mysocket->socket_id,vl_bufData,vl_packetSize,p_flags);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
}
if(debug > 2){
/*fprintf(stdout,"size of st_packetData:%d\n",sizeof(st_packetData));
fprintf(stdout,"vl_packetSize:%d\n",vl_packetSize);
fprintf(stdout,"Memcopied-data:%s\n",vst_packet.vst_data);
fprintf(stdout,"Memcopied-pad:%s\n",vst_packet.vst_pad);
fprintf(stdout,"Memcopied-size:%d\n",vst_packet.vst_size);//sss
fprintf(stdout,"Data from buffer:%s\n",p_buffer);
fprintf(stdout,"data:%s\n",vl_bufData+sizeof(vst_packet.vst_size)+sizeof(vst_packet.vst_pad));*/
fprintf(stdout,"Copied data:%-10.6s\n",vl_bufData);
fprintf(stdout,"---------------------------\n");
}
//if(vl_err >=(sizeof(vst_packet.vst_size)+ sizeof(vst_packet.vst_pad))) //sss
if(vl_err >=(sizeof(unsigned int)+ strlen(vg_change_socket)))
{
vl_err = vl_err-(sizeof(unsigned int) + strlen(vg_change_socket));//sss
}
if(debug > 2)
{
fprintf(stdout,"The socket id is :%d.. Thread:%s\n",p_mysocket->socket_id,p_mysocket->vst_nm_thread);
fprintf(stdout,"The data tx %d.. Thread:%s\n",vl_err,p_mysocket->vst_nm_thread);
}
free((void *)vl_bufData);
}
else
{
vl_err = send(p_mysocket->socket_id,p_buffer,p_len,0);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
if(debug>1)
{
fprintf(stdout,"The socket id is :%d.. Thread:%s\n",p_mysocket->socket_id,p_mysocket->vst_nm_thread);
fprintf(stdout,"The data tx %d.. Thread:%s\n",vl_err,p_mysocket->vst_nm_thread);
}
}
/* return number of bytes sent */
return vl_err;
}