簡體   English   中英

兩台64位機器之間的TCP套接字編程

[英]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調用返回的值中獲取大小。 我最好的猜測是,你收到的字節數確實少於預期。


雖然發送和接收結構非常方便,但它通常是徒勞的。 手動序列化數據或使用一些顯式機制可能是要走的路。

你沒有向我們展示sendrecv部分,這更可能是錯誤的。 我的猜測是你正確接收到數組中的第一項,並且它們在某些時候“變成”垃圾,是不是?

好吧,@ cnicutar是正確的,但讓我稍微擴展一下......

首先,當您調用send您必須檢查返回值並查看是否已傳輸所有字節。 如果您的結構很大(例如,大於底層套接字緩沖區),則需要多次調用來傳輸整個結構。 recv相同, 不要指望你會在一次recv調用中得到整個消息 ,不要指望每個recv都會收到相應send調用發送的相同數量的數據。 始終檢查已接收的字節數,並在必要時再次調用recv (指向傳入緩沖區中的正確位置並減少要接收的字節數)。

所以可能發生了什么,你沒有收到足夠的數據(也許你甚至沒有傳輸所有數據),只有你的傳入緩沖區的開頭才被填滿。 因此,結構的其余部分是垃圾或(當您調用memset )保持初始化為零。

另請注意, sendrecv返回ssize_t而不是size_t因為負值是可能的(表示錯誤)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM