2013-05-12 90 views
0

夥計!在多線程服務器中使用套接字

我正在* nix下開發c上的多線程服務器。在進程的主線程中,我有監聽套接字,它等待連接(接受)。當它獲得一個連接(接受返回客戶端套接字描述符)時,我會啓動新的pthread,並創建一些例程,該例程將響應請求並關閉客戶端套接字描述符。它看起來像這樣:

while(1) 
{ 
    sock_cl =(int *)malloc(sizeof(int)); 
    *sock_cl = accept(sock_serv, NULL, NULL); 
    pthread_create(thread, attr, answer, sock_cl); 
} 

接聽功能:

void *answer(void *arg) 
{ 
    int sock_cl; 
    char *buf; 
    ssize_t r; 
    lsres_t *ans; 
    char *path; 
    char status[STATUS_SIZE]; 

    sock_cl = *((int *)arg); 
    if((buf = (char *)malloc(BUF_SIZE + 1)) == NULL) 
    { 
     sprintf(status, "%i\n", -1); 
     send_data(sock_cl, status, STATUS_SIZE); 
     close(sock_cl); 
     free(arg); 
     return NULL; 
    } 
    memset(buf, '\0', BUF_SIZE + 1); 

    if((r = recv(sock_cl, buf, BUF_SIZE, 0)) <= 0) 
    { 
     close(sock_cl); 
     free(arg); 
     return NULL; 
    } 

    path = strtok(buf, "\r\0"); 
    if((ans = lscreate()) == NULL) 
    { 
     sprintf(status, "%i\n", -1); 
     send_data(sock_cl, status, STATUS_SIZE); 
    } 
    else 
    { 
     if(myls(path, ans) != 0) 
     { 
      sprintf(status, "%i\n", -1); 
      send_data(sock_cl, status, STATUS_SIZE); 
     } 
     else 
     { 
      sprintf(status, "%i\n", ans->status); 
      send_data(sock_cl, status, STATUS_SIZE); 
      send_data(sock_cl, ans->buf, ans->written_size); 
     } 
     lsdestroy(ans); 
    } 

    close(sock_cl); 
    free(arg); 
    return NULL; 
} 

在接聽功能我們可以調用recv從客戶recive數據和發送一些答案。它在Linux系統(Arch,Debian,Ubuntu)下運行良好,但是當我嘗試在Unix(Solaris)下運行它時,我得到了segv掉落recv函數。問題不在緩衝區中,因爲如果我嘗試在與答覆函數相同的線程中調用answer函數,我沒有分段下降。所以在使用帶有pthreads的套接字時存在一些問題。

請告訴我任何解決方案如何在多線程服務器中使用套接字。感謝您的未來答案!

回答

0

我覺得在UNIX recv函數失敗,分割faut是由於代碼段free(args);

+0

即使沒有自由分段故障發生也沒有。 – tegoo 2013-05-12 15:30:58

+0

請檢查sock_cl在回答中有效() – akhil 2013-05-12 15:35:07

+0

也我認爲sock_cl =(int)(* arg);是足夠的,而不是sock_cl = *((int *)arg); – akhil 2013-05-12 15:37:19

-1

可能,這可能是

close(sock_cl); 
    free(arg); 
    return NULL; 

這sock_cl是線程間共享的原因,因爲有沒有同步的答案功能,因爲你釋放這個指針的其他線程綁定崩潰,如果可能的話,你通過在valgrind中運行檢查這個相同的程序腐敗。

+0

我認爲這不是一個原因,因爲每個線程都有自己的指向sock_cl的指針(它在每次迭代中都是malloc)。線程有不同的指針。 – tegoo 2013-05-12 15:01:13

+0

oops剛剛實現 – 2013-05-12 15:13:18

1

在Solaris上,通常需要使用-mt進行編譯才能正確編譯和鏈接多線程程序。如果你不使用它,你會看到隨機的線程崩潰。

+0

此密鑰適用於cc。我正在使用以下密鑰的gcc: -lpthread -D_REENTRANT -lrt -lsocket -lnsl – tegoo 2013-05-13 11:39:28