C++ 通过TCP套接字发送XDR的好方法
我有一些通过TCP套接字发送的XDR数据包。 下面是我的代码片段:C++ 通过TCP套接字发送XDR的好方法,c++,tcpsocket,xdr,C++,Tcpsocket,Xdr,我有一些通过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(
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);
XDR;
int i;
xdrrec_create(&ixdr,0,0,重新解释_cast(&ui)和underflow,0);
ixdr.x_op=XDR_解码;
cout数据包大小无关。当XDR库要求您阅读时,您只需阅读即可。XDRXDR_rec
流类型处理其中包含长度字的流。您所要做的就是为它提供您自己的读写功能。我已经22年没有这样做了,但这并不困难。我不明白为什么你认为你需要“在开始解码之前接收完整的数据包”。你没有xdr\u rec
将根据需要随时调用您的read()
函数
问题是xdr_uint32_t正在阻塞
否。XDR函数没有阻塞。一个也没有。阅读来源。阻塞的是read()
函数
因此,如果我将read和xdr_uint32_t放在同一个线程中,并且在完成整个流的读取之前运行xdr_uint32_t
那没有道理。看看我上面写的。”当XDR库要求您阅读时,您只需阅读。而不是之前
这可能会阻止应用程序。所以我可能需要在两个单独的线程中读取套接字和解码
不。您似乎不明白xdr\U rec的工作原理。创建一个xdr_rec
对象,并为其提供一个读回调函数和一个写回调函数。从那时起,您只需调用您喜欢的任何XDR例程,它们会根据需要调用读或写回调。你根本不给他们打电话。不需要先“读取整个流”
您应该在一个线程中完成所有这些操作。您使用的是什么XDR库?您好,我使用的是Linux,我只是简单地将数据包大小包括在内。当XDR库要求您阅读时,您只需阅读即可。其中一种XDR流类型处理包含长度字的流,但已经超过20年了,我不记得是哪种类型。您是否建议使用xdrrec而不是xdrmem?是的,它是XDR\u rec
,您可以提供自己的读写函数。