[英]Sending data from a struct, socket programming
我有一個學校的作業,一部分是使用套接字編程將一組int chars char *從客戶端發送到服務器。 發送整數或字符可以正常工作,但是有什么辦法可以將整個結構作為一個包發送? 了解有關序列化的信息,但我似乎無法使其工作。 這是一個代碼片段:
The struct looks like this:
struct Msg
{
int a;
char b;
char *user;
};
Client:
init variables and such...
int netcom(char* ip, int port) {
sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
// clear the structure
bzero(&serveraddr, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
// add the server adress
inet_pton(AF_INET, ip, &serveraddr.sin_addr);
// add the port number
serveraddr.sin_port = htons(port);
// connect
connect (sd,(struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in));
}
int sendPkg(struct Msg msg) {
send(sd, &msg, sizeof(msg), 0);
}
服務器接收的部分如下所示:
char buf[100];
recv(sd[i], buf, sizeof(buf)-1, 0);
客戶端發送完全正常,而服務器收到很好。 但是我不知道我要發送什么,以及如何正確閱讀。 這就是我的問題。 如何使用套接字正確地從struct
發送數據。
直接發送結構似乎很吸引人,因為您可以在一個調用中完成它……更糟的是:有時它實際上效果很好! 這是一個陷阱。
這是一個陷阱的第一個原因是,例如,在您的情況下,其中一個元素是指針。 除非在極少數情況下,否則接收方將獲得該端無用的指針,該指針指向對發送過程有效的內存。
第二個不太明顯的原因是陷阱,原因是套接字一側的結構(在內存中)在另一側的布局可能不相同。 這是計算機體系結構和編譯器設置的功能,因此很難相信它會“正常”。 這種陷阱很容易擺脫一段時間,尤其是在開發過程中,在測試過程中,您可能在測試的每一側都具有兼容的體系結構。
最好的辦法是單獨發送每個字段,即使這樣很痛苦。 但是,通過為此代碼創建專用的發送器和接收器功能,可以通過對代碼應用一些面向對象的設計來減輕痛苦。 這些函數非常了解內容和順序,並將其打包為較小的發送(對於char *
,可能需要在字符串數據之前包含一個長度)。
正如我所描述的,打包發送可以很好,只要結構沒有從套接字的一側更改為另一側即可,但是您可能要警惕在一端使用不同版本的結構...說一個新(或不存在)字段。 為了解決這個問題,您可以考慮標記發送的數據(而不是假設“首先發送a
,然后b
等”)。
研究許多JSON庫來管理序列化將是有益的。 這為您提供了一種易於閱讀的格式,可以解決我在此處提出的所有問題,並且幾乎所有常見的編程語言都可以使用JSON庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.