[英]Send C struct over TCP socket
我已經看到了很多與我的問題相關的答案,但是我真的不能在我的情況下使用它。
我正在Linux域下使用帶有C語言的套接字編程來構建網絡模塊。 我必須實現一個函數,該函數可以發送包含int,char,char *和其他一些結構(嵌套結構)的結構。
struct EnQuery
{
char type[6]; // insert, select , update , delete
char * columns; //note here, it's an array of big, {name, age, sex, position, email} not in string
struct Values * values; //an array of values(another struct), {tom, 23, male, student, tom@compan.com} is represented by the second struct values, not in string
struct condition * enCondition; // array of condition, "name=tom and age>30" is represnted by the third struct condition
short len;
short rn;
};
struct Values
{
char * doc;
char key[2];
char s;
};
struct condition
{
short k;
struct condition * children;
};
以上是我要發送的結構。 我聲明變量,並使用send()函數通過套接字發送。
我將如何通過套接字發送char *? 還是有辦法方便地調整char數組的長度?
PS我不能使用外部庫
我將如何通過套接字發送char *?
顯然,發送指針值不是一件有用的事,因為指針不會指向接收計算機上任何有效的東西。
因此,您不必發送指針,而必須發送它指向的數據。 一種典型的實現方法是首先發送指針指向的字節數:
uint32_t sLen = strlen(doc)+1; // +1 because I want to send the NUL byte also
uint32_t bigEndianSLen = htonl(sLen);
if (send(sock, &bigEndianSLen, sizeof(bigEndianSLen), 0) != sizeof(bigEndianSLen)) perror("send(1)");
....然后發送字符串的字節:
if (send(sock, doc, sLen, 0) != sLen) perror("send(2)");
在接收端,您將執行相反的操作:首先接收字符串的長度:
uint32_t bigEndianSLen;
if (recv(sock, &bigEndianSLen, sizeof(bigEndianSLen), 0) != sizeof(bigEndianSLen)) perror("recv(1)");
uint32_t sLen = ntohl(bigEndianSLen);
...,然后接收字符串的數據:
char * doc = malloc(sLen+1);
if (recv(sock, doc, sLen, 0) != sLen) perror("recv(2)");
doc[sLen] = '\0'; // paranoia: make sure the string is terminated no matter what
請注意,此示例代碼有點天真,因為它無法正確處理send()或recv()返回傳給它們的字節數以外的值的情況。 生產質量代碼將正確處理錯誤(例如,通過關閉連接),並且還將正確處理以下情況:send()或recv()發送/接收僅傳輸請求的某些字節(通過調用send()/稍后再次將recv()用作剩余的未發送/未接收字節)。
您需要做出選擇:使用“打包”功能在發送方對內存中的數據結構進行序列化,使用解壓縮功能通過線進行發送並反序列化(直接使用),或者直接對套接字動態地進行序列化/反序列化(更好)之后,作為第一個版本的優化)。
您可以從以下開放源代碼中獲得一些啟發,例如: https : //code.google.com/p/protobuf-c/
用“類型編號”定義一個枚舉。 使用您的示例:
Tchar Tstring Tshort Tint TEnQuery TValues Tcondition Tpop
定義一些標志類型,這些標志位與類型相關:
Tarray -- array of base type現在輸出類型編號。 緊隨其后的是實際數據。 例如,要輸出一個Values結構:
Tvalues\n TString,文檔數據(inc EOS)\n Tchar | Tarray,2,關鍵數據\n Tchar的價值\n TPOP任何聚合(例如struct)都會執行與Tpop配對的隱式“ Tpush”
現在,您有了一個字節流,可以使用某種狀態機來遞歸處理該字節流。 對於上述所有類型,您將需要遞歸函數進行導出/導入。 導入時,關鍵是類型編號是您要調度的對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.