[英]TCP socket programming between two 64bit machines
我正在嘗試使用C語言中的TCP套接字編程來實現客戶端 - 服務器程序通信。它位於安裝了Linux OS的兩台64位機器之間。 我想在兩個進程之間傳遞一個c-struct。
為此,我嘗試使用pack - unpack()函數。
請考慮以下代碼段
/*---------------------------------------------------------
on the sending side I have:
---------------------------------------------------------*/
struct packet {
int64_t x;
int64_t y;
int64_t q[maxSize];
} __attribute__((packed));
int main(void)
{
// build packet
struct packet pkt;
pkt.x = htonl(324);
pkt.y = htonl(654);
int i;
for(i = 0; i< maxSize; i++){
pkt.q[i] = i; **// I also try pkt.q[i] = htonl(i);**
}
// and then do the send
}
/*-----------------------------------------------------------------------------
in the receiving side:
-----------------------------------------------------------------------------*/
struct packet {
int64_t x;
int64_t y;
int64_t q[maxSize];
} __attribute__((packed));
static void decodePacket (uint8_t *recv_data, size_t recv_len)
{
// checking size
if (recv_len < sizeof(struct packet)) {
fprintf(stderr, "received too little!");
return;
}
struct packet *recv_packet = (struct packet *)recv_data;
int64_t x = ntohl(recv_packet->x);
int64_t y = ntohl(recv_packet->y);
int i;
printf("Decoded: x=%"PRIu8" y=%"PRIu32"\n", x, y);
for(i=0;i<maxSize;i++){
**//int64_t res = ntohl(recv_packet->q[i]); I also try to print res**
printf("%"PRIu32"\n" , recv_packet->q[i]);
}
}
int main(int argc, char *argv[]){
// receive the data and try to call decodePacket()
int8_t *recv_data = (int8_t *)&buf; //buf is the data received
size_t recv_len = sizeof(buf);
**decode_packet(recv_data, recv_len);**
}
//-----------------------------------------------------------------------------
現在的問題是我正在結構中正確地接收x和y的值,但是對於結構中的數組q我收到一個奇怪的數字,可能是內存grabage值,(我嘗試使用memset()填充在從另一方接收數據之前,通過零來排列數組,在這種情況下接收到全零的值)
我不明白為什么我沒有收到struct中數組的正確值。
請注意 ,在放入struct之前我嘗試使用和不使用htonl(),而在另一方面:在從struct解碼數組時使用和不使用ntohl()
任何幫助將不勝感激,
size_t recv_len = sizeof(buf); decode_packet(recv_data, recv_len);
這段代碼確保將錯誤的大小傳遞給decode_packet
。 因此,當decode_packet
繼續檢查recv_len < sizeof(struct packet)
,該測試毫無意義 - 無論接收到多少字節,它都將始終通過 。
您需要從recv
調用返回的值中獲取大小。 我最好的猜測是,你收到的字節數確實少於預期。
雖然發送和接收結構非常方便,但它通常是徒勞的。 手動序列化數據或使用一些顯式機制可能是要走的路。
你沒有向我們展示send
和recv
部分,這更可能是錯誤的。 我的猜測是你正確接收到數組中的第一項,並且它們在某些時候“變成”垃圾,是不是?
好吧,@ cnicutar是正確的,但讓我稍微擴展一下......
首先,當您調用send
您必須檢查返回值並查看是否已傳輸所有字節。 如果您的結構很大(例如,大於底層套接字緩沖區),則需要多次調用來傳輸整個結構。 與recv
相同, 不要指望你會在一次recv
調用中得到整個消息 ,不要指望每個recv
都會收到相應send
調用發送的相同數量的數據。 始終檢查已接收的字節數,並在必要時再次調用recv
(指向傳入緩沖區中的正確位置並減少要接收的字節數)。
所以可能發生了什么,你沒有收到足夠的數據(也許你甚至沒有傳輸所有數據),只有你的傳入緩沖區的開頭才被填滿。 因此,結構的其余部分是垃圾或(當您調用memset
)保持初始化為零。
另請注意, send
和recv
返回ssize_t
而不是size_t
因為負值是可能的(表示錯誤)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.