2013-10-30 48 views
2

我正在做套接字編程,以實現我的應用程序中不同實體之間的通信。發送消息時,我在消息前加上消息的長度,然後用\ 0終止消息。我曾經的recv()在一個循環中,如下所示:指針在recv()函數中的錯誤

void receive(int socket) 
{ 
    int num_of_bytes_read = 0, msg_len; 
    char *msg = NULL, *msg_p = NULL; 
    char recv_buf[MAX_LEN]; 

    while(num_of_bytes_read = recv(socket, recv_buf, MAX_LEN, 0)) 
    { 
     if(msg == NULL) 
     { 
      memcpy(&msg_len, message, 4); 
      msg_len = ntohl(msg_len); 

      if((msg = (char *)(sizeof(char) * msg_len)) == NULL) 
       systemError("Could not receive new message\n"); 

      printf("%p\n", msg); /* prints 0xe!! Why is the address not 4B long??*/ 
      msg_p = msg; 
     } 

     if(memcpy(&msg_p, recv_buf, num_of_bytes_read) == NULL) 
      systemError("memcpy failed in receive()\n"); 

     msg_p += num_of_bytes_read; 
    } 


    printf("%p\n", msg);     /* prints (nil) !!!!!*/ 
    printf("%p\n", msg + sizeof(uint32_t)); /* prints 0x4 */ 

    /* pass the a pointer to the beginning of the message skipping msg_len*/ 
    int res = processMessage(msg + sizeof(uint32_t)); 
} 

當我運行程序我明明得到分段錯誤,出現以下錯誤: 消息=爲0x4

有什麼不對味精 ??有人可以請幫助。

+2

無關:這是您*以前想要檢查'recv'是否工作的最後一種方法。該函數在出錯時返回「-1」,並且仍然會傳遞您的while-condition。然後考慮代碼的其餘部分用'-1'來表示'num_of_bytes_read'值。 – WhozCraig

回答

2

msg = (char *)(sizeof(char) * msg_len)

要設置msg根據該msg_len一些地址。實際上與msg駐留在內存中沒有任何關係......

+2

+1另外一個原因是你從來沒有在C中投過malloc,但我必須承認這是我第一次見到它隱藏了這個事實,工程師忘了輸入這個詞**'malloc' ***!這幾乎是值得的獨創性的獎勵點。 – WhozCraig

+0

@WhozCraig良好的皮卡 - 我開始看看代碼應該分散的東西。看起來你已經釘了它。當然OPs代碼仍然缺少+1來允許'\ 0'。 – John3136

+1

說真的。我想最喜歡這個,只是爲了讓一個同事明天工作。我從未見過以前26年的專業工程,並且我看到過很多*。 – WhozCraig

3
while(num_of_bytes_read = recv(socket, recv_buf, MAX_LEN, 0)) 

這已經是錯誤的了。您應測試> 0。如果num_of_bytes爲零,則應關閉插槽,如果爲-1,則應記錄相關的errno,perror(),並關閉插座,並在這兩種情況下停止閱讀。

if(msg == NULL) 
    { 
     memcpy(&msg_len, message, 4); 

只要message指向四個字節的可尋址內存,這將成功。你沒有提供關於這一點的信息。目的仍然不明確。

 msg_len = ntohl(msg_len); 

這裏你正在假設message指出了神奇包含已奇蹟般地被設置爲您準備把作爲消息長度的值的int四個字節。爲什麼,我不知道。再一次,你沒有提供有關這一點的信息。

 if((msg = (char *)(sizeof(char) * msg_len)) == NULL) 

這完全是無稽之談。在那裏有一個malloc()失蹤?

  systemError("Could not receive new message\n"); 

無意義的錯誤消息。問題似乎是關於分配內存,但這是任何人的猜測。它當然與接收消息無關。

 printf("%p\n", msg); /* prints 0xe!! Why is the address not 4B long??*/ 

在這裏你似乎認爲地址應該是4B長。我不知道爲什麼。

if(memcpy(&msg_p, recv_buf, num_of_bytes_read) == NULL) 

您將數據複製到地址msg_p.這是沒有意義的。此外,由於上面的環路條件不正確,此時num_of_bytes_read可能爲-1,因此可能發生任何事情,包括嘗試複製0xffffffff字節。

 systemError("memcpy failed in receive()\n"); 

你可以得到該行的唯一方法是,如果msg_p地址爲空,這是不可能的。在memcpy()調用中從&msg_p中刪除&。現在,如果msg_p爲零,您只能撥打systemError(),這將導致SEGV,因此您仍然無法進入該線路。這裏指出了一點預防性編碼。

msg_p += num_of_bytes_read; 

再次num_of_bytes_read可能是-1在這一點上,發送您的指針向後而不是轉發。

printf("%p\n", msg);     /* prints (nil) !!!!!*/ 

無表示msg爲零。

printf("%p\n", msg + sizeof(uint32_t)); /* prints 0x4 */ 

0x4再次表示msg爲零。

您需要在指定的區域改進您的代碼。