gpt4 book ai didi

c++ - 通过 TCP 套接字发送 XDR 的好方法

转载 作者:行者123 更新时间:2023-11-30 05:30:19 28 4
gpt4 key购买 nike

我有一些通过 TCP 套接字发送的 XDR 数据包。这是我的代码片段:

const size_t BUFFER_LENGTH = 2000;
XDR xdr;
char *buffer = new char[BUFFER_LENGTH];
xdrmem_create(&xdr, buffer, BUFFER_LENGTH, XDR_ENCODE);

const std::string requestId = request->getPacket()->getRequestId();
MyPacket responcePacket(requestId, status,message);
responcePacket.serialize(&xdr);

unsigned int byteSent = write(*socketDescriptor_, buffer, BUFFER_LENGTH);
delete buffer;
if(byteSent!=BUFFER_LENGTH)
{
throw Exception("Error during write!");
}

数据包序列化如下:

class MyPacket:

void MyPacket::serialize(XDR* xdr)
{
// Convert Enum to int
int _messageType = (int) messageType_;
uint32_t _status = (uint32_t) status_;

//Copy all strings to c_string
char *_requestId = new char[requestId_.length() + 1];
std::strcpy(_requestId,requestId_.c_str());

char *_message = new char[message_.length() + 1];
std::strcpy(_message,message_.c_str());

bool status = xdr_int(xdr, &_messageType) &&
xdr_string(xdr, &_requestId, REQUESTID_LENGTH_) &&
xdr_u_int(xdr, &_status ) &&
xdr_string(xdr, &_message, MESSAGE_LENGTH_);

delete _requestId;
delete _message;

if(!status)
{
throw new Exception("Error while serializing MyPacket.");
}
}

....

}

作为第一个测试,我假设最大数据包大小为 2000,而我总是从另一端读取 2000。作为第一次测试,这项工作正常,但我希望能够在不需要时发送和接收更少的信息。此外,我不想在增加服务器上的数据包大小时重新编译客户端。

我想知道是否有一种正确的方法来发送和接收这个流,而不必自己预先设置数据包大小。如果我必须自己添加这个,有没有办法轻松获得 xdr 大小?

干杯,

添加:我尝试如下使用 xdr_rec 缓冲区:

XDR ixdr;
int i;
xdrrec_create (&ixdr,0,0,reinterpret_cast<char*> (&ui),&underflow,0);
ixdr.x_op = XDR_DECODE;

cout << "xdrrec_eof: " << xdrrec_eof (&ixdr) <<endl;
cout << "xdrrec_skiprecord: " << xdrrec_skiprecord (&ixdr) <<endl;

for(j=0;j<10;j++){
xdr_uint32_t (&ixdr, &i);
cerr << "i: " << i << endl;
}xdr_destroy (&ixdr);

如果我为它提供一个正确的 10 uint32 缓冲区,一切都很好。现在,我尝试在缓冲区的末尾剪切一些字节,我期待 xdrrec_eofxdrrec_skiprecord 给我一个错误。这就是我想用来检测我还没有收到所有数据的东西。相反发生的是,两者都成功返回并且 xdr_uint32_t 阻止代码执行。所以我现在真正想念的是一种在使用 xdr_uint32_t 开始解码之前检测我是否已收到完整数据包的方法。有什么建议吗?

最佳答案

数据包大小无关紧要。当 XDR 库要求您阅读时,您只需要阅读。 XDR xdr_rec 流类型处理其中包含长度字的流。您所要做的就是为其提供您自己的读写功能。我这样做已经 22 年了,但这并不困难。我不明白为什么您认为您需要“在开始 [ing] 解码之前接收完整的数据包”。你不知道。 xdr_rec 将根据需要经常调用您的 read() 函数。

The problem is that xdr_uint32_t is blocking

没有。 XDR 函数不阻塞。不是其中之一。阅读源代码。阻塞的是 read() 函数。

so if i have the read and the xdr_uint32_t in the same thread and i run xdr_uint32_t before having finished reading the whole stream

这没有意义。阅读我上面写的内容。 “当 XDR 图书馆要求您阅读时,您只需要阅读。”之前没有。

this risks to block the application. So probably i need to have the socket reading and the decoding in 2 separate threads.

没有。您似乎不了解 xdr_rec 的工作原理。您创建一个 xdr_rec 对象并为其提供读取回调函数和写入回调函数。从那里开始,您只需调用您喜欢的任何 XDR 例程,它们就会根据需要调用读取或写入回调。你根本不调用他们。不需要先“阅读整个流”。

你应该在一个线程中完成所有这些。

关于c++ - 通过 TCP 套接字发送 XDR 的好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36005359/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com