我看到很多与我的问题相关的答案,但我真的不能在我的条件下使用它。
我正在使用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数组长度?
P.S我不能使用外部库
答案 0 :(得分:2)
我如何通过套接字发送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()稍后再次用于剩余的未发送/未接收的字节。)
答案 1 :(得分:2)
您需要做出选择:使用“pack”函数序列化发送端内存中的数据结构,通过线路发送并使用解包函数(直接)反序列化,或者直接动态序列化/反序列化socket(最好在第一个版本的优化之后完成)。
您可以从这个开源代码中获得一些灵感,例如: https://code.google.com/p/protobuf-c/
答案 2 :(得分:0)
使用“类型编号”定义枚举。使用您的示例:
Tchar Tstring Tshort Tint TEnQuery TValues Tcondition Tpop
定义一些得到或类型的标志位:
Tarray -- array of base type现在输出类型编号。跟随实际数据。例如,输出一个Values结构:
Tvalues Tstring,data for doc (inc EOS) Tchar | Tarray,2,key data Tchar,s value Tpop任何聚合(例如struct)都会执行与Tpop配对的隐含“Tpush”
现在您有一个字节流,您可以使用各种状态机递归处理。您需要递归函数来导出/导入所有上述类型。在导入时,关键是类型编号是您在
上发送的内容答案 3 :(得分:-3)