2013-01-03 29 views
3

我正在寫在C++客戶端應用程序經由UDP的廣播接收的二進制數據,但是我無法接收任何超出前4個字節,而不管緩衝區大小。我在Wireshark中檢查了數據包,我可以看到我的機器正在接收大約1200字節的數據。當我將它與我的客戶正在接收的數據進行比較時,我可以看到我正在收到數據包,但是剩餘的數據丟失了。這裏是我的代碼:的recv只得到第一個4個字節包

#define BUFFERSIZE 4096 
int main() 
{ 
    struct addrinfo hints, *servinfo, *p; 
    int sockfd, i, nbyt; 

    int *buf = (int*) malloc(BUFFERSIZE); 

    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_INET; 
    hints.ai_socktype = SOCK_DGRAM; 
    hints.ai_flags = AI_PASSIVE; 

    getaddrinfo(NULL, "9011", &hints, &servinfo); 

    sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); 
    bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen); 

    FILE *file; 
    file = fopen("file.txt", "w+"); 

    for (i=0;i<=45;i++) 
    { 
     nbyt = recv(sockfd, buf, BUFFERSIZE, 0);    
     fprintf(file, "%s %d; %s %x\n", "Bytes received:", nbyt, "Message:", *buf); 
    } 

    fclose(file); 
    close(sockfd); 
    free(buf); 

    printf("%s\n", "Execution ended."); 

    return 0; 
} 

的一些數據我收到的一個例子:

Bytes received: 1131; Message: 5b0 
Bytes received: 1131; Message: 5b3 
Bytes received: 1131; Message: 5b6 
Bytes received: 1092; Message: 4e0 

我試過設置插座與MSG_DONTWAIT標誌無阻塞的,因爲這將固定問題的一個類似的Python應用程序,然而這僅會返回錯誤:

Bytes received: -1; Message: 0 

我是比較新的C++和插座,所以它可能有一些,我只是沒有看到。希望有人能幫我弄清楚什麼是錯的?如有必要,我可以提供更多信息。

+0

其中C++ ...... – neagoegab

+0

fprintf中是問題。 – neagoegab

+0

數據在緩衝區中。 %x使printf在buf指向的位置查找一個無符號的十六進制整數。所以你的程序正在做你要做的事情。你可能還想要別的東西。請注意,在您的recv()調用中,您設置了BUFFERSIZE _bytes_的限制,而您分配的緩衝區至少大四倍,具體取決於您的平臺的int大小。分配字符緩衝區,像現在這樣爲數據調用recv(),並將緩衝區指針傳遞給處理程序以獲取二進制數據。 printf()不是查看二進制內容的好選擇。 – arayq2

回答

4

你接受它就好了。你的調試代碼只是不會做你認爲它做的事情。

x說明符printf打印在十六進制unsigned int型參數。您的平臺上的整數可能是32位。所以你只打印前4個字節。

如果你想打印在十六進制整個緩衝區,你需要寫循環做自己(或使用圖書館,當然)。例如,我警告你我的C有點生疏(而這遠遠不是執行此操作的最佳方式)...另外,這假定你的緩衝區總是sizeof(int)的倍數, ,或者它會丟失一些數據:

nbyt = recv(sockfd, buf, BUFFERSIZE, 0);    
fprintf(file, "%s %d; %s\n", "Bytes received:", nbyt, "Message:"); 
for (offset = 0; offset < nbyt/sizeof(int); ++offset) { 
    fprintf(file, "%x ", buf[offset]); 
} 
fprintf(file, "\n"); 
+0

這就是問題所在!謝謝你的協助!我一直在錯誤的地方尋找問題。現在我知道我正在把一切都弄好,這只是我搗毀細節的問題。再次感謝並感謝所有回答的人! – user1896512

+0

@ user1896512請隨時通過點擊旁邊的複選框來接受答案......或者不,它取決於您。 – derobert

1

*buf在你的代碼意味着從接收數據的數組的第一個整數,所以要打印只有四個接收UDP有效載荷的第一個字節。

1

儘管已經提到的格式錯誤,如果你收到一個「\ 0」字符,一個格式化打印與%s將繩剪斷那裏,無論字符的實際數量的好評。

出於調試明文,我用下面的代碼:

char escaped_char(char c) 
{ 
    char escapable[12] = {'\a','\b','\f','\n','\r','\t','\v','\\','\'','\"','\?','\0'}; 
    char escaped[12] = { 'a', 'b', 'f', 'n', 'r', 't', 'v','\\','\'','\"', '?', '0'}; 

    const char* escapable_end = escapable + 12; 
    const char* ec; 

    for(ec = escapable;ec != escapable_end;++ec) 
    { 
     if(c == *ec) return escaped[ec-escapable]; 
    } 
    return 0; 
} 

/** 
* @param buf  input buffer to escape 
* @param len  length of contents in buf 
* @param outlen pointer to an integer, which receives the length of the returned string 
* @return   A newly allocated, C style escaped string, NULL on error 
* @warning   A returned string must be freed with free() 
*/ 
char* aescape(const char* buf,size_t len,size_t* outlen) 
{ 
    const char* buf_end = buf + len; 
    const char* c; 
    char ec; 
    char* result; 

    assert(buf && outlen); 

    (*outlen) = len; 

    for(c = buf;c != buf_end;++c) 
    { 
     if(escaped_char(*c)) 
     { 
      ++*outlen; 
     } 
    } 
    result = malloc((*outlen)+1); 
    assert(result != NULL); 
    if(result) 
    { 
     if((*outlen) > len) 
     { 
      char* out = result; 
      for(c = buf;c != buf_end;++c) 
      { 
       ec = escaped_char(*c); 
       if(ec) 
       { 
        *out++ = '\\'; 
        *out++ = ec; 
       } 
       else 
       { 
        *out++ = *c; 
       } 
      } 
     } 
     else 
     { 
      memcpy(result,buf,len); 
     } 
     result[(*outlen)] = '\0'; 
    } 
    else 
    { 
     (*outlen) = 0; 
    } 
    return result; 
}