2011-05-04 89 views
1

我在具有相同IP地址但具有不同端口的客戶端和服務器的同一臺計算機上以C語言實現多線程客戶端 - 服務器套接字編程。我已經在C環境中使用pthread概念實現了它。但是我可以看到只有我的客戶端線程正在運行,而我的服務器線程一旦到達'accept()'例程就停止了。 我想知道可能是什麼問題。如果有任何人能找出我犯了一個錯誤那麼這將是非常有益的C中的多線程客戶端 - 服務器套接字編程

我的客戶端代碼如下所示:

void *client_connect(void *arg) 
{ 

    int client_socket; 
    struct sockaddr_in Serv_Addr; 
    struct sockaddr_in Client_Addr; 
    int addrlen=sizeof(Client_Addr); 

    char send_buffer_client[] = {"server message"}; 
    char recv_buffer_client[1024]; 
    int nbytes; 

    client_socket = lwip_socket(AF_INET, SOCK_STREAM, 0); 
    if (client_socket < 0) ; 

    memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr)); 
    Serv_Addr.sin_family = AF_INET; 
    Serv_Addr.sin_len = sizeof(Serv_Addr); 
    Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4"); 
    Serv_Addr.sin_port = 9999; 
    memset((char *)&Client_Addr, 0, sizeof(Client_Addr)); 
    Client_Addr.sin_family = AF_INET; 
    Client_Addr.sin_len = sizeof(Client_Addr); 
    Client_Addr.sin_addr.s_addr = inet_addr("1.2.3.4"); 
    Client_Addr.sin_port = 5555; 

    lwip_connect(client_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr)); 

    while (1) { 

       do{ 
        nbytes = lwip_recv(client_socket, recv_buffer_client, sizeof(recv_buffer_client),0); 
        if (nbytes>0) lwip_send(client_socket, send_buffer_client, sizeof(send_buffer_client), 0); 

        printf("server message = %s\n", recv_buffer_client); 
       } while (nbytes>0); 

       sleep(10); 

     } 
     lwip_close(client_socket); 
} 

我的服務器代碼:

void *server_connect(void *arg) 
{ 

    int server_socket; 
    struct sockaddr_in Serv_Addr; 
    struct sockaddr_in Client_Addr; 
    int addrlen=sizeof(Client_Addr); 
    int clientfd; 
    char send_buffer[] = {"Server message"}; 
    char recv_buffer[1024]; 
    int nbytes_server, client_length; 

    server_socket = lwip_socket(AF_INET, SOCK_STREAM, 0); 
    if (server_socket < 0) 
    printf("could not create server socket"); 
    else 
    printf("created SERVER socket"); 

    memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr)); 
    Serv_Addr.sin_family = AF_INET; 
    Serv_Addr.sin_len = sizeof(Serv_Addr); 
    Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4"); 
    Serv_Addr.sin_port = 9999; 


    client_length = sizeof(Client_Addr); 
    if (lwip_bind(server_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr)) < 0) {   
      printf("could not BIND"); 
    } 

    if (lwip_listen(server_socket, 20) != 0){ 
      printf("could not BIND"); 
    } 
    while (1) { 
       lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length);     

       do{ 
       nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer),0); 
       if (nbytes_server>0){lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0);} 

       printf("client message = %s\n", recv_buffer); 
       }while(nbytes_server>0); 
       sleepms(10); 
     } 
     lwip_close(server_socket); 
} 

void main(void) 
{ 
    pthread_t client_thread; 
    pthread_t server_thread; 

    pthread_create(&server_thread, NULL, server_connect, NULL); 
    pthread_create(&client_thread, NULL, client_connect, NULL); 

    while(1){ 
     sleepms(1); 
     } 
} 

請讓我知道如果我做了錯誤的方式

問候 德布

+0

你需要嘗試重新格式化您的代碼,它可能給線索。同樣在客戶端,如果(client_socket <0);看起來不正確。 – ColWhi 2011-05-04 14:44:31

+1

首先,我會添加「\ n」並在printf失敗後退出/返回;代碼在錯誤之後仍然繼續。接下來,跳過創建線程,並直接調用server_connect。然後嘗試通過telnet連接,看看你是否連接。 – 2011-05-04 15:02:20

回答

0

如果您位於同一臺計算機上,則您使用的IP地址1.2.3.4不是本地主機的典型地址,該地址應爲127.0.0.1。除非實際上使用路由器或其他方式(如IP地址1.2.3.4)創建了本機的IP地址,否則該地址無法解析,即使您嘗試在同一臺計算機上運行客戶端和服務器,他們不會找到對方,因爲沒有辦法將1.2.3.4解析到網絡上的給定機器上。

此外,您不需要將服務器鎖定到特定的IP地址,只需使用netinet/in.h中的常量INADDR_ANY即可將套接字綁定到系統上的任何接口。在客戶端,雖然您仍然需要正確的IP地址,但是,如果它是本地主機,則可以使用127.0.0.1。

0

(1)它看起來好像客戶端和服務器都在等待接收某些東西,然後再回顯它。有人必須先談談。

(2)我沒有看到你的lwip_accept返回一個新的套接字與客戶端進行通信。您最終在偵聽套接字上執行recv/send。

(3)而且,這裏考慮您的代碼:

while (1) 
{ 
    lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length); 

    do 
    { 
     nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer), 0); 

     if (nbytes_server > 0) 
     { 
      lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0); 
     } 

     printf("client message = %s\n", recv_buffer); 
    } 
    while (nbytes_server > 0); 

    sleepms(10); 
} 

您閱讀和回聲的消息,但從來沒有關閉套接字(可能是明智的,因爲它是監聽套接字!),並立即循環回到上接受阻斷再次。如果客戶端沒有再次連接,你會被永久接受。

(4)您不需要這些sleepms()調用。在主要中使用pthread_join(),然後擺脫其餘部分。無論如何,它看起來像你所有的呼叫阻止。

2

這裏的ATLEAST 3個錯誤:

lwip_accept()返回一個新的socket描述符,你應該使用從客戶端讀取,而不是從原始服務器套接字讀取(還要注意lwip_accept將阻塞,直到有人實際上是連接到服務器)。如果你是一個小端機器上

您的端口號可能會脫過,他們在網絡字節順序是通常情況下,你應該做的 Serv_Addr.sin_port = htons(9999);和同一客戶端端口 - htons把從主機端短network endian

您沒有發送任何數據!你的客戶端等待服務器發送一些東西。但是你的服務器不發送任何東西,它等待客戶端發送一些東西。什麼都不會發生。

檢查lwip_connect也會失敗,檢查errno如果你的環境提供了它,什麼不順心

相關問題