2011-11-07 14 views
2

私は2つのデーモンを持っていて、AはBに話しています。Bはポートでリッスンしており、AはそのポートへのTCP接続を開きます。 AはBへのソケットをオープンすることができますが、ソケットを実際に書き込もうとするとSIGPIPEを取得するので、Bがオープンソケットを閉じている可能性があります。SIGPIPE実行中のプログラム

しかし、gdbの両方のデーモンに接続すると、データを処理するコードが呼び出される前にSIGPIPEが実行されます。初期の書き込みは決して成功しないため、リスナーはデータの受信からトリガーされるため、この種の意味があります。私の質問は - データが送信される前にデーモンBがソケットを閉じる原因になる可能性がありますか?ソケットは開いた後に1マイクロ秒未満で閉じられるので、タイムアウトや何かのものではないと思っています。私は数日のうちにこれを噛んでいたので、追跡する可能性の洗濯物のリストが大好きです。私はかなりアイデアがありません。要求されたよう

、ここに受け入れ、通信を処理するコードは次のとおりです。

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

注:私はこのコードを書いていません。

+1

書き込みの直前と直後の 'A'プログラムの' 'events '' poll() 'がソケット上にあるのは興味深いかもしれません。 – aschepler

+0

最初の答えを見て問題が見つからない場合は、アイデアをお寄せいただきありがとうございます。 – dbeer

答えて

1

同じハンドルを2回クローズしようとすると、あなたが混乱し、プログラムのどこか他の場所にいる可能性はありますか?

これは非常に簡単にこれを行うことができます。

ヒント:systraceは、これが起こっているかどうかを判断できます。

+0

これはおそらく私の問題です。私は調査します。 – dbeer

+0

シャットダウン(sock、2)がダウンした場合、これが起こりますか?それからクローズ(靴下)。 ? – dbeer

+0

いいえ、close()がshutdown()の直後にある場合、それが問題になる可能性はあまりありません。 – Joshua

関連する問題