2012-03-27 80 views
1

我想使用memcpy()函數來存儲從read()中獲取的一些二進制數據。如何使用memcpy()函數?

基本上,我想存儲buf中我緩衝:

#define MAX_BUFFER_SIZE 256 
//... 
char * 
httpget(const char * domain, const int port, const char * headers) 
{ 
    int sockfd; 
    int buf_size = MAX_BUFFER_SIZE; 

    struct sockaddr_in sock_addr; 
    struct hostent * host; 

    char * buffer; 
    char * newbuf; 
    char * tbuf; 

    sockfd = socket(AF_INET,SOCK_STREAM,0); 

    if(sockfd == -1) 
    { 
     return NULL; 
    } 

    host = gethostbyname(domain); 

    if(NULL == host) 
    { 
     close(sockfd); 
     return NULL; 
    } 

    memset(&sock_addr, '\0', sizeof(sock_addr)); 
    sock_addr.sin_family = AF_INET; 
    memcpy(&sock_addr.sin_addr.s_addr, 
      host -> h_addr, 
      host -> h_length); 

    sock_addr.sin_port = htons(port); 

    if(connect(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) == -1) 
    { 
     close(sockfd); 
     return NULL; 
    } 

    if(write(sockfd, headers, strlen(headers) + 1) == -1) 
    { 
     close(sockfd); 
     return NULL; 
    } 

    buffer = malloc(MAX_BUFFER_SIZE); 
    tbuf = malloc(MAX_BUFFER_SIZE); 

    if(buffer == NULL || tbuf == NULL) 
    { 
     return NULL; 
    } 

    int bytesloaded = 0; 
    int readed; 

    while((readed = read(sockfd, tbuf, MAX_BUFFER_SIZE)) > 0) 
    { 
     if(bytesloaded + readed >= buf_size) 
     { 
      buf_size = buf_size + MAX_BUFFER_SIZE; 
      newbuf = realloc(buffer, buf_size); 

      if(newbuf != NULL) 
      { 
       buffer = newbuf; 
      } 
      else 
      { 
       return NULL; 
      } 
     } 

     memcpy(buffer, tbuf, readed); 
     bytesloaded += readed; 
    } 

    close(sockfd); 
    printf("buffer = %s", buffer); 
    return buffer; 
} 

,但是當我的printf( 「%s」 時,緩衝區);我從二進制文件中只獲得了HTTP Headers和�PNG字符,其內容長度爲7007。如何解決這個問題?我希望你明白這一點。任何幫助非常感謝。提前感謝。

+0

這是重新輸入的代碼嗎?'buffe'肯定看起來像編譯器會捕獲的錯字。如果你的縮短代碼真的失敗了,這真的是最好的 - 調試只存在於本網站上的代碼是沒有意義的...... – sarnold 2012-03-27 00:53:27

+2

請注意,如果第二次內存分配失敗,你將泄漏第一次內存分配中分配的256字節。 – sarnold 2012-03-27 00:54:22

+0

@sarnold:是錯字。我添加了我的真實代碼。 – Jack 2012-03-27 01:00:52

回答

3

我想你想:

memcpy(buffer + bytesloaded, buf, readed); 

您沒有看到整個響應當您嘗試轉儲使用printf("%s",buffer)因爲.png圖像中的響應發送它是二進制數據,這可能包含空'\0'字節,並且printf()將在該點停止。

你有各種各樣的其他選項以檢查在響應返回的數據(或有關它的信息):看buffer在調試器,轉儲bytesloaded變量,使用將其轉換爲十六進制的功能傾倒buffer顯示和/或將響應正文(在標題後面的標題和CR/LF之後)寫入.png文件,並在顯示圖像的東西中查看它。

+0

我更新我的代碼。查看。我只收到HTTP頭,例如:HTTP/1.0 200 OK Date:Tue,27 Mar 2012 01:01:54 GMT 服務器:Mono.WebServer2/0.2.0.0 Unix Last-Modified:Sun,3月25日2012 GMT 14時50分48秒 X-ASPNET-版本:2.0.50727 的Content-Length:7007 緩存控制:私人 內容類型:圖像/ PNG 連接:關閉 PNG ' – Jack 2012-03-27 01:03:25

+0

@Jack :看到我更新的答案。 – 2012-03-27 03:48:03

1

在memcpy中存在一個輸入錯誤,指的是buffe而不是緩衝區,雖然它可能只出現在帖子中,而不是在實際的代碼中(我不相信它會與它一起編譯),如果它那麼這肯定是問題所在。

更新:雖然其他答案表明可能有一個空字節,但是在png頭部規範中沒有空字節應該是頭部分的一部分,所以它唯一可能的地方是body,但是由於你沒有收到任何數據,那麼唯一的選擇可能是,如果它是身體的第一件事情,我認爲這是真的,那麼你可以嘗試使用不同的信息來源,如另一個圖像或另一個網址,如果問題依然存在於所有的png圖像上,那麼它就是printf和頭文件之間的東西(如果頭文件中有空字節,那麼無論如何它都是有價值的)。

但是請注意,在字母PNG出現CRLF之後出現EOF,而如果printf會出現問題,它會很有趣,但如果出現這個問題,那麼轉儲到文件一定不是解決方案除非你用png查看器打開它。

事實上,您還沒有包含套接字源代碼,因此如果您自己編寫的代碼確保它不會停留在第一個EOF上,因爲它是png標頭的一部分。

+0

我更新我的代碼。查看。 :) – Jack 2012-03-27 01:03:45

+0

更新了答案 – 2012-03-27 09:34:22

1

由於printf(3)格式化指令%s會將字節打印爲字符,直到遇到ASCII NUL字符。 PNG format可能會允許一個NUL也許只要第九個字節 - 前八個字節是0x89,PNG,然後一些空白字符來發現特定種類的空白變形。

我建議使用不同的printf(3)格式說明符來查看有問題的數據 - 或將其寫入調試文件,以便您可以使用常見的十六進制編輯器編輯它以驗證其內容。