2016-03-07 123 views
2

我想開發一個UDP客戶端服務器程序。這裏是我的代碼:UDP套接字 - 服務器沒有收到任何數據

服務器

int main(int argc, char *argv[]) { 
    struct sockaddr_in client, server; 
    int s, i=0; 
    socklen_t n; 
    char buf[4]; 
    s=socket(AF_INET,SOCK_DGRAM,0); 
    server.sin_family=AF_INET; 
    server.sin_port=atoi(argv[1]); 
    inet_pton(AF_INET, "localhost", &(server.sin_addr)); 
    bind(s,(struct sockaddr *)&server,sizeof(server)); 
    n=sizeof(client); 

    while(1) { 
     recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&client, &n); 
     printf("%s", buf); 
    } 
    close(s); 
    return 0; 
} 

客戶

int main (int argc, char *argv[]) { 
    struct sockaddr_in client, server; 
    int s, n; 
    char buf[30]; 
    char temp[4]; 
    s=socket(AF_INET,SOCK_DGRAM,0); 
    server.sin_family=AF_INET; 
    server.sin_port=atoi(argv[2]); 
    inet_pton(AF_INET, argv[1], &(server.sin_addr)); 

    n=sizeof(server); 

    while(1) { 
     scanf("%s", buf); 
     fflush(stdin); 
     sendto(s, buf, sizeof(buf), 0, (struct sockaddr *) &server, n); 
    } 
    close(s); 
    return 0; 
} 

在自然界中非常基本的,沒有任何的錯誤處理。服務器輸出任何客戶端發送。

在我測試某些東西時,我忘記刪除/釋放動態分配的內存後,它停止在我的Ubuntu機器上工作。它在不同的Linux服務器上工作得很好。

任何想法可能會造成這種情況?未封閉的端口,內存泄漏?我該如何解決?

+0

'fflush(stdin);'調用*未定義的行爲*,所以不要使用它。 – MikeCAT

+0

'printf(「%s」,buf);'也可能調用*未定義的行爲*如果buf中的內容不是以null結尾的字符串。在打印之前正確終止「字符串」,或以其他方式打印。 – MikeCAT

+0

以前,我的程序被困在無法讀取數據,所以我不得不強制清理標準輸入緩衝區。任何更好的選擇? – ExtremistEnigma

回答

0

有問題,你的方法:

  • fflush(stdin);調用未定義的行爲。如果你想閱讀並丟棄由用戶輸入該行的其餘部分,使用:

    scanf("%*[^\n]"); /* consume all remaining chars on the line, if any */ 
    scanf("%*c");  /* consume the linefeed if any */ 
    
  • 客戶端代碼應該只是發送字符串,可能與一個分離器,但不是全部的緩衝區,部分這是未初始化:

    sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&server, n); 
    
  • 服務器代碼應該空終止從客戶機接收到的緩衝液:

    while(1) { 
        ssize_t nr = recvfrom(s, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&client, &n); 
    
        if (nr >= 0) { 
         buf[nr] = '\0'; 
         printf("%s", buf); 
        } 
    } 
    
  • 客戶端和服務器都應該優雅地處理文件和系統調用失敗的結束。

0

首先,作爲@kaylum提到的,你需要檢查錯誤。除此之外,我看到幾個問題:

  • inet_pton()不會將主機名轉換爲地址。通常情況下,你不想綁定到服務器端 上的特定IP地址;相反,將其設置爲INADDR_ANY。在客戶端,127.0.0.1將用於發送到同一臺計算機上的服務器。
  • 您需要將您的端口號轉換爲網絡字節順序 htons()
  • 您發送30個字節,但您的接收緩衝區只有4個字節長。 有人提到你不應該發送整個30字節的 緩衝區,但這取決於你和你的協議。您只需要 即可處理髮送的任何內容。
  • 正如其他人所說,fflush(stdin)是不正確的; fflush()用於沖洗輸出 ,但stdin是輸入文件。
  • scanf("%s", buf)不會將輸入限制爲緩衝區的大小, 這樣可能會導致問題。改爲使用fgets()
相關問題