簡體   English   中英

通過 TCP 套接字發送 XDR 的好方法

[英]Good way for sending XDR over TCP Socket

我有一些通過 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_uint32_t 有什么建議嗎?

數據包大小無關緊要。 您只需要在 XDR 庫要求您閱讀時閱讀即可。 XDR xdr_rec流類型處理其中包含長度字的流。 您所要做的就是為它提供您自己的讀寫功能。 我做這件事已經 22 年了,但這並不困難。 我不明白為什么你認為你需要“在開始[ing]解碼之前接收一個完整的數據包”。 你沒有。 xdr_rec將根據需要經常調用您的read()函數。

問題是 xdr_uint32_t 正在阻塞

不會。XDR 功能不會阻塞。 不是其中之一。 閱讀源碼。 阻塞的是read()函數。

所以如果我在同一個線程中讀取和 xdr_uint32_t 並且我在完成讀取整個流之前運行 xdr_uint32_t

那沒有意義。 閱讀我上面寫的內容。 “你只需要在 XDR 庫要求你閱讀時閱讀。” 以前不是。

這有阻止應用程序的風險。 所以可能我需要在 2 個單獨的線程中進行套接字讀取和解碼。

不。您似乎不了解xdr_rec工作原理。 您創建一個xdr_rec對象並為其提供讀取回調函數和寫入回調函數。 從那時起,您只需調用您喜歡的任何 XDR 例程,它們會根據需要調用讀取或寫入回調。 你根本不打電話給他們。 不需要先“閱讀整個流”。

你應該在一個線程中完成所有這些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM