2012-02-23 173 views
0

我有一個客戶端 - 服務器應用程序,我正在使用tcp套接字。在從客戶端發送send()請求時,我總是遇到總線錯誤,程序終止。現在我做了一個小維基百科搜索,文章將總線錯誤歸因於(不存在的物理地址,未對齊的內存訪問以及訪問已被截斷的mmapped文件)。我發送的結構只有三個整數和一個枚舉實例,所以我不認爲對齊是一個問題。下面是代碼中的相關片段:Linux中的TCP總線錯誤

typedef struct _commsg 
{ 
    RequestType requestType; 
    int client_pid; 
    int request_id; 
    int sector; 
}ComMsg; 
在主

/* Create a reliable, stream socket using TCP */ 
if ((sock_id = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 
    DieWithError("socket() failed\n"); 

/* Construct the server address structure */ 
memset(&echoServAddr, 0, sizeof(echoServAddr));  /* Zero out structure */ 
echoServAddr.sin_family  = AF_INET;    /* Internet address family */ 
echoServAddr.sin_addr.s_addr = inet_addr(loopback_addr); /* Server IP address */ 
echoServAddr.sin_port  = htons(SERVER_PORT); /* Server port */ 

/* Establish the connection to the echo server */ 
if (connect(sock_id, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
    DieWithError("connect() failed"); 


if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) != sizeof(ComMsg)) 
    DieWithError("send() sent a different number of bytes than expected"); 

和服務器端:

recv(clntSocket_fd, &_commsg, sizeof(ComMsg), 0); 

在此先感謝。

+1

'&_commsg' ????? – 2012-02-23 15:36:58

+1

要麼有重要的東西丟失,要麼你的編譯器真的很奇怪! – 2012-02-23 15:37:53

+0

套接字ID有效嗎?什麼是'_commsg'?請提供更多的代碼。 – 2012-02-23 15:40:52

回答

0

正如send(2)手冊頁所述「send() 和write(2)之間的唯一區別是標誌的存在。使用零標誌參數, send()等價於write(2 )「

正如Stevens在他的Unix Network Programming Book中所述。 「流 插座(例如,TCP套接字)表現出的行爲與該讀寫 功能,從正常的文件I/O而不同。一個讀或在 流套接字寫可能輸入或輸出更少的字節比請求」

因此可能想要用這種方式來測試錯誤:

if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) < 0) 

而不是測試發送的字節。實際上沒有問題時,您可能會關閉您的應用程序 。

除了通過網絡發送的結構通常不是一個好主意 ,因爲你可能會落入比你的,首選的方式正在與字節串不同的其他系統連接 時ENDIANESS相關的問題。

1

您是否正在編譯您的應用程序,並提供完整警告(例如,使用gcc,-Werror)?你應該。總線錯誤幾乎肯定意味着你正在訪問一個錯誤的指針,違反了你傳遞給函數的參數中的API等。試着編譯完整的警告,修正你看到的每一個錯誤,看看是否能解決你的問題。 (2)和recv(2)通常使用read(2)和write(2)。

+2

也嘗試'valgrind' – 2012-02-24 22:32:41

0

運行你的客戶端strace -esendgdb可能會受到啓發。