C 带运行程序的SIGPIPE
我有两个守护进程,A正在与B对话。B正在监听一个端口,A打开到该端口的tcp连接。A可以将套接字打开到B,但当它试图实际写入所述套接字时,我得到一个SIGPIPE,因此我试图找出B可以关闭打开的套接字的位置 但是,如果我连接到gdb中的两个守护进程,则SIGPIPE会在调用任何用于处理数据的代码之前发生。这样做是有意义的,因为初始写入永远不会成功,并且侦听器是从接收数据中触发的。我的问题是-什么会导致守护进程B在发送任何数据之前关闭套接字?插座在打开后不到一微秒就关闭了,所以我认为这不可能是超时或类似的情况。我希望能有一份详细的清单,列出可以追踪的各种可能性,因为我已经细细琢磨了几天了,我几乎没有什么想法了 根据要求,以下是接受和处理通信的代码:C 带运行程序的SIGPIPE,c,unix,daemon,sigpipe,C,Unix,Daemon,Sigpipe,我有两个守护进程,A正在与B对话。B正在监听一个端口,A打开到该端口的tcp连接。A可以将套接字打开到B,但当它试图实际写入所述套接字时,我得到一个SIGPIPE,因此我试图找出B可以关闭打开的套接字的位置 但是,如果我连接到gdb中的两个守护进程,则SIGPIPE会在调用任何用于处理数据的代码之前发生。这样做是有意义的,因为初始写入永远不会成功,并且侦听器是从接收数据中触发的。我的问题是-什么会导致守护进程B在发送任何数据之前关闭套接字?插座在打开后不到一微秒就关闭了,所以我认为这不可能是超时
{
extern char *PAddrToString(pbs_net_t *);
int i;
int n;
time_t now;
fd_set *SelectSet = NULL;
int SelectSetSize = 0;
int MaxNumDescriptors = 0;
char id[] = "wait_request";
char tmpLine[1024];
struct timeval timeout;
long OrigState = 0;
if (SState != NULL)
OrigState = *SState;
timeout.tv_usec = 0;
timeout.tv_sec = waittime;
SelectSetSize = sizeof(char) * get_fdset_size();
SelectSet = (fd_set *)calloc(1,SelectSetSize);
pthread_mutex_lock(global_sock_read_mutex);
memcpy(SelectSet,GlobalSocketReadSet,SelectSetSize);
/* selset = readset;*/ /* readset is global */
MaxNumDescriptors = get_max_num_descriptors();
pthread_mutex_unlock(global_sock_read_mutex);
n = select(MaxNumDescriptors, SelectSet, (fd_set *)0, (fd_set *)0, &timeout);
if (n == -1)
{
if (errno == EINTR)
{
n = 0; /* interrupted, cycle around */
}
else
{
int i;
struct stat fbuf;
/* check all file descriptors to verify they are valid */
/* NOTE: selset may be modified by failed select() */
for (i = 0; i < MaxNumDescriptors; i++)
{
if (FD_ISSET(i, GlobalSocketReadSet) == 0)
continue;
if (fstat(i, &fbuf) == 0)
continue;
/* clean up SdList and bad sd... */
pthread_mutex_lock(global_sock_read_mutex);
FD_CLR(i, GlobalSocketReadSet);
pthread_mutex_unlock(global_sock_read_mutex);
} /* END for each socket in global read set */
free(SelectSet);
log_err(errno, id, "Unable to select sockets to read requests");
return(-1);
} /* END else (errno == EINTR) */
} /* END if (n == -1) */
for (i = 0; (i < max_connection) && (n != 0); i++)
{
pthread_mutex_lock(svr_conn[i].cn_mutex);
if (FD_ISSET(i, SelectSet))
{
/* this socket has data */
n--;
svr_conn[i].cn_lasttime = time(NULL);
if (svr_conn[i].cn_active != Idle)
{
void *(*func)(void *) = svr_conn[i].cn_func;
netcounter_incr();
pthread_mutex_unlock(svr_conn[i].cn_mutex);
func((void *)&i);
/* NOTE: breakout if state changed (probably received shutdown request) */
if ((SState != NULL) &&
(OrigState != *SState))
break;
}
else
{
pthread_mutex_lock(global_sock_read_mutex);
FD_CLR(i, GlobalSocketReadSet);
pthread_mutex_unlock(global_sock_read_mutex);
close_conn(i, TRUE);
pthread_mutex_unlock(svr_conn[i].cn_mutex);
pthread_mutex_lock(num_connections_mutex);
sprintf(tmpLine, "closed connections to fd %d - num_connections=%d (select bad socket)",
i,
num_connections);
pthread_mutex_unlock(num_connections_mutex);
log_err(-1, id, tmpLine);
}
}
else
pthread_mutex_unlock(svr_conn[i].cn_mutex);
} /* END for i */
/* NOTE: break out if shutdown request received */
if ((SState != NULL) && (OrigState != *SState))
return(0);
/* have any connections timed out ?? */
now = time((time_t *)0);
for (i = 0;i < max_connection;i++)
{
struct connection *cp;
pthread_mutex_lock(svr_conn[i].cn_mutex);
cp = &svr_conn[i];
if (cp->cn_active != FromClientDIS)
{
pthread_mutex_unlock(svr_conn[i].cn_mutex);
continue;
}
if ((now - cp->cn_lasttime) <= PBS_NET_MAXCONNECTIDLE)
{
pthread_mutex_unlock(svr_conn[i].cn_mutex);
continue;
}
if (cp->cn_authen & PBS_NET_CONN_NOTIMEOUT)
{
pthread_mutex_unlock(svr_conn[i].cn_mutex);
continue; /* do not time-out this connection */
}
/* NOTE: add info about node associated with connection - NYI */
snprintf(tmpLine, sizeof(tmpLine), "connection %d to host %s has timed out after %d seconds - closing stale connection\n",
i,
PAddrToString(&cp->cn_addr),
PBS_NET_MAXCONNECTIDLE);
log_err(-1, "wait_request", tmpLine);
/* locate node associated with interface, mark node as down until node responds */
/* NYI */
close_conn(i, TRUE);
pthread_mutex_unlock(svr_conn[i].cn_mutex);
} /* END for (i) */
return(0);
}
{
外部字符*填充字符串(pbs_net_t*);
int i;
int n;
现在是时候了;
fd_set*SelectSet=NULL;
int-SelectSetSize=0;
int MaxNumDescriptors=0;
字符id[]=“等待请求”;
字符模板[1024];
结构timeval超时;
长起始状态=0;
if(SState!=NULL)
OrigState=*SState;
timeout.tv_usec=0;
timeout.tv_sec=等待时间;
选择setsize=sizeof(char)*get_fdset_size();
SelectSet=(fd_set*)calloc(1,SelectSetSize);
pthread_mutex_lock(全局_sock_read_mutex);
memcpy(SelectSet、GlobalSocketReadSet、SelectSetSize);
/*selset=readset;*//*readset是全局的*/
MaxNumDescriptors=get_max_num_descriptors();
pthread_mutex_unlock(全局_sock_read_mutex);
n=选择(MaxNumDescriptors,SelectSet,(fd_set*)0,(fd_set*)0和超时);
如果(n==-1)
{
如果(errno==EINTR)
{
n=0;/*中断,循环*/
}
其他的
{
int i;
结构统计fbuf;
/*检查所有文件描述符以验证它们是否有效*/
/*注意:selset可能会被失败的select()修改*/
对于(i=0;icn\U活动!=来自客户端)
{
pthread_mutex_unlock(svr_conn[i].cn_mutex);
继续;
}
如果((现在-cp->cn\u lasttime)cn\u authen&PBS\u NET\u CONN\u NOTIMEOUT)
{
pthread_mutex_unlock(svr_conn[i].cn_mutex);
继续;/*不要超时此连接*/
}
/*注意:添加与连接关联的节点的信息-NYI*/
snprintf(tmpLine,sizeof(tmpLine),“到主机%s的连接%d在%d秒后超时-关闭过时的连接\n”,
我
PAddrToString(&cp->cn\U addr),
PBS_NET_MAXCONNECTIDLE);
日志错误(-1,“等待请求”,tmpLine);
/*定位与接口关联的节点,将节点标记为down,直到节点响应*/
/*纽约*/
关闭连接(i,正确);
pthread_mutex_unlock(svr_conn[i].cn_mutex);
}/*结束(i)*/
返回(0);
}
注意:我没有写这段代码。有没有可能你把程序搞砸了,在程序的其他地方你试图关闭同一个句柄两次 这对你来说很容易
提示:systrace可以确定是否发生了这种情况。查看
poll()
程序中A
的套接字上在尝试写入之前和之后显示了哪些“事件”可能会很有趣。感谢您的想法,如果我在查看第一个答案时没有发现问题,我将跟踪它。这很可能是我的问题。我会调查。如果我关闭了一个系统,会不会发生这种情况(sock,2);然后是一只(袜子)?不,即使是这样,如果在shutdown()之后立即关闭()也不太可能出现问题。@dbeer好吧,如果sock
的值不是您要关闭的套接字,那么请确定。但最好向我们展示接受和处理客户机的B代码。