使用tpl通过套接字发送结构,以便使用c进行序列化
在阅读了一些相关的问题之后,我决定使用来序列化我的结构,以便通过套接字发送和接收它们。我无法理解如何使用套接字发送和接收tpl映像。调用使用tpl通过套接字发送结构,以便使用c进行序列化,c,sockets,serialization,C,Sockets,Serialization,在阅读了一些相关的问题之后,我决定使用来序列化我的结构,以便通过套接字发送和接收它们。我无法理解如何使用套接字发送和接收tpl映像。调用tpl\u dump函数时,服务器端出现segfault错误 我知道套接字在两端都工作,因为我以前使用代码来回发送字符串。我还能够使用tpl在客户端上创建和读取tpl映像,没有任何问题 这并不是我最终想要来回发送的结构,但我希望能够弄清楚这个示例,以便将来可以这样做。我知道我在传入缓冲区和tpl\u转储之间处理不当。我仍在学习C语言(我前面的问题证明了这一点),
tpl\u dump
函数时,服务器端出现segfault错误
我知道套接字在两端都工作,因为我以前使用代码来回发送字符串。我还能够使用tpl在客户端上创建和读取tpl映像,没有任何问题
这并不是我最终想要来回发送的结构,但我希望能够弄清楚这个示例,以便将来可以这样做。我知道我在传入缓冲区和tpl\u转储之间处理不当。我仍在学习C语言(我前面的问题证明了这一点),所以如果我的代码中有明显的错误,我很抱歉
编辑
尼古拉指出的问题已在下面的代码中更正。但是,服务器代码记录错误:tpl_加载到非根节点,并且仍然在tpl_解包(tn,0)处出现故障代码>
客户端代码:
tpl_node *tn;
void *addr;
size_t len;
struct ci {
char c;
int i;
};
struct ci sample = {'a', 1};
tn = tpl_map("S(ci)", &sample); /* pass structure address */
tpl_pack(tn, 0);
tpl_dump(tn, TPL_MEM, &addr, &len );
tpl_free(tn);
send(sockfd, addr, len, 0);
tpl_node *tn;
void *addr;
size_t len;
struct ci {
char c;
int i;
};
struct ci sample = {'a', 1};
tn = tpl_map("S(ci)", &sample); /* pass structure address */
tpl_pack(tn, 0);
tpl_dump(tn, TPL_MEM, &addr, &len );
tpl_free(tn);
send(sockfd, addr, len, 0);
服务器代码:
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
//error handling
} else {
tpl_node *tn;
struct ci {
char c;
int i;
};
struct ci recieve;
tpl_map("S(ci)", &recieve);
tpl_load(tn, TPL_MEM, &buf, &nbytes );
tpl_unpack(tn, 0);
tpl_free(tn);
char buf[256]; // buffer for client data
int nbytes;
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
//error handling
} else {
tpl_node *tn;
struct ci {
char c;
int i;
};
struct ci receive;
tpl_map("S(ci)", &receive);
tpl_load(tn, TPL_MEM, buf, nbytes );
tpl_unpack(tn, 0);
tpl_free(tn);
printf("Struct: {%c,%d}\n", receive.c, receive.i);
如果((nbytes=recv(i,buf,sizeof buf,0))看起来您至少在客户端上误用了tpl_dump
,那么第二个参数应该是void**
,而不是int*
。宏将分配的缓冲区的地址存储到addr
整数中,因此您正在发送地址(加上一些垃圾),而不是发送到服务器的数据。服务器端的调用顺序看起来也有问题。
仔细查看您的来源:
- 从
buf
和len
中移除符号(&);tpl\u负载
需要void*
和size\u t
;
- 完成后,您需要
释放()
内存;
- 您需要注意短套接字读取-您可能会收到比通过TCP套接字读取发送的更少(或更多)的消息。
下面是一个没有套接字的简单完整示例:
#include <stdlib.h>
#include <stdio.h>
#include "tpl.h"
int main( int argc, char* argv[] )
{
char* buffer;
size_t i, len;
tpl_node *tn;
struct ci { char c; int i; } s = {'a', 1}, s1;
printf( "input {%c,%d}\n", s.c, s.i );
tn = tpl_map( "S(ci)", &s ); /* pass structure address */
tpl_pack( tn, 0 );
tpl_dump( tn, TPL_MEM, &buffer, &len );
tpl_free( tn );
printf( "size = %lu\n", len );
tn = tpl_map( "S(ci)", &s1 );
tpl_load( tn, TPL_MEM, buffer, len );
tpl_unpack( tn, 0 );
tpl_free( tn );
free( buffer );
printf( "output {%c,%d}\n", s1.c, s1.i );
return 0;
}
#包括
#包括
#包括“tpl.h”
int main(int argc,char*argv[])
{
字符*缓冲区;
尺寸i,len;
tpl_节点*tn;
结构ci{char c;int i;}s={'a',1},s1;
printf(“输入{%c,%d}\n”,s.c,s.i);
tn=tpl_映射(“S(ci)”,&S);/*传递结构地址*/
第三方物流包装(tn,0);
tpl_转储(tn、tpl_内存、缓冲区和len);
无第三方物流(tn);
printf(“大小=%lu\n”,len);
tn=tpl_图(“S(ci)”、&s1);
tpl_负载(总氮、tpl_膜、缓冲器、透镜);
tpl_开箱(tn,0);
无第三方物流(tn);
自由(缓冲);
printf(“输出{%c,%d}\n”,s1.c,s1.i);
返回0;
}
对于每个请求,下面是一个使用套接字的成功实现:
客户端代码:
tpl_node *tn;
void *addr;
size_t len;
struct ci {
char c;
int i;
};
struct ci sample = {'a', 1};
tn = tpl_map("S(ci)", &sample); /* pass structure address */
tpl_pack(tn, 0);
tpl_dump(tn, TPL_MEM, &addr, &len );
tpl_free(tn);
send(sockfd, addr, len, 0);
tpl_node *tn;
void *addr;
size_t len;
struct ci {
char c;
int i;
};
struct ci sample = {'a', 1};
tn = tpl_map("S(ci)", &sample); /* pass structure address */
tpl_pack(tn, 0);
tpl_dump(tn, TPL_MEM, &addr, &len );
tpl_free(tn);
send(sockfd, addr, len, 0);
服务器代码:
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
//error handling
} else {
tpl_node *tn;
struct ci {
char c;
int i;
};
struct ci recieve;
tpl_map("S(ci)", &recieve);
tpl_load(tn, TPL_MEM, &buf, &nbytes );
tpl_unpack(tn, 0);
tpl_free(tn);
char buf[256]; // buffer for client data
int nbytes;
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
//error handling
} else {
tpl_node *tn;
struct ci {
char c;
int i;
};
struct ci receive;
tpl_map("S(ci)", &receive);
tpl_load(tn, TPL_MEM, buf, nbytes );
tpl_unpack(tn, 0);
tpl_free(tn);
printf("Struct: {%c,%d}\n", receive.c, receive.i);
char buf[256];//客户端数据缓冲区
整数字节;
如果((nbytes=recv(i,buf,sizeof buf,0))有人查看此线程,Eric de Araujo 2009年7月16日14:49的帖子(他的更正代码)只有在您更正其服务器代码部分中的一个错误时才有效:
tpl_map("S(ci)", &receive);
必须更改为:
tn = tpl_map("S(ci)", &receive);
感谢您指出服务器上的调用出现故障。我将客户端的代码从“int addr”更改为“void*addr”这是正确的吗?是的,它仍然存在故障。问题已经用我最近的代码和错误更新。这解决了正确处理tpl方面的问题。在我纠正了缓冲区和套接字的处理后,我能够成功地通过结构。