簡體   English   中英

如何從套接字讀取接收自定義數據類型?

[英]How to receive a custom data type from socket read?

我想收到一個數據(自定義類型說CMYType)我有以下代碼;

using namespace boost::asio;

streambuf receivedStreamBuffer;
streambuf::mutable_buffers_type bufs;
bufs = receivedStreamBuffer.prepare( sizeof(CMYType) );
std::size_t length = read( *m_pReciver->ConSocket(), 
                           buffer(bufs, sizeof(CMYType)),  
                           transfer_all(),
                           ec);

關於如何將receivedStreamBuffer轉換為CMYType類型的對象的任何想法?!

你的代碼“可以”實際工作。 但是,正如Christophe指出的那樣,您需要考慮許多問題。

TCP / IP編程

在您的評論中,您提到您是TCP / IP編程的新手。 我建議你閱讀“Beej的網絡編程指南” 這是一篇簡短的(約20頁)和體面的介紹,涵蓋了網絡編程的幾乎所有方面,包括下面的內容。 這是非常值得的,它是免費的。

字節序

這是網絡通信的一般基本問題。 如果您無法控制軟件運行的機器,則絕對需要處理它。 或者如果你想要可移植代碼。 只有在絕對確定通信的兩台(所有)機器具有相同的架構時,才可以跳過此步驟

如果您需要了解更多問題, 三個 網站都是很好的起點。

序列化

序列化既是問題的概括,又是可以解決上述問題的“銀彈”(如果正確應用的話)。 基本思想是將您的數據類型(結構)轉換為“串行流”,可以通過任何通道(網絡)傳輸並轉換回您的類型。 Boost有一個可用於此的序列化庫

請記住其他人提到的便攜性和ABI警告。

如果您在評論中說,您確定您的客戶端和服務器在這些方面是兼容的:

對於POD數據

如果您的類型滿足POD要求,則可以使用buffer_cast

實際上你可以使用buffer函數隱式地使用它:

住在Coliru

#include <boost/asio.hpp>
#include <iostream>
#include <vector>
#include <boost/thread.hpp>

struct CMYType {
    float a,b,c;
};

static_assert(std::is_pod<CMYType>::value, "Not bitwise serializable");

static std::ostream& operator<<(std::ostream& os, CMYType const& cmy) {
    return os << "[" << cmy.a << "," << cmy.b << "," << cmy.c << "]";
}

static boost::mutex mx;

void server() {
    boost::system::error_code ec;
    using namespace boost::asio;

    io_service svc;
    ip::tcp::acceptor acc(svc, ip::tcp::endpoint{ {}, 6767 });

    {
        ip::tcp::socket sock(svc);
        acc.accept(sock, ec);

        CMYType data;
        std::size_t length = read(sock, buffer(&data, sizeof(data)), ec);
        boost::lock_guard<boost::mutex> lk(mx);
        std::cout << "length:" << length << " data: " << data << "\n";
    }

    {
        ip::tcp::socket sock(svc);
        acc.accept(sock, ec);

        std::vector<CMYType> data(10);
        std::size_t length = read(sock, buffer(data), ec);

        boost::lock_guard<boost::mutex> lk(mx);
        std::cout << "length:" << length << " data: { ";

        for(auto& cmy : data)
            std::cout << cmy << ", ";

        std::cout << " }\n";
    }
}

void client() {
    boost::system::error_code ec;
    using namespace boost::asio;

    io_service svc;

    {
        ip::tcp::socket sock(svc);
        sock.connect({ {}, 6767 }, ec);

        CMYType data { 1, 2, 3 };

        std::size_t length = write(sock, buffer(&data, sizeof(data)), ec);
        boost::lock_guard<boost::mutex> lk(mx);
        std::cout << "sent: " << length << " bytes\n";
    }

    {
        ip::tcp::socket sock(svc);
        sock.connect({ {}, 6767 }, ec);

        std::vector<CMYType> data { 
            { 1,  2,  3  }, { 4,  5,  6  }, { 7,  8,  9  }, { 10, 11, 12 }, { 13, 14, 15 },
            { 16, 17, 18 }, { 19, 20, 21 }, { 22, 23, 24 }, { 25, 26, 27 }, { 28, 29, 30 },
        };
        std::size_t length = write(sock, buffer(data), ec);

        boost::lock_guard<boost::mutex> lk(mx);
        std::cout << "sent: " << length << " bytes\n";
    }

}

int main() {
    boost::thread_group tg;
    tg.create_thread(server);
    tg.create_thread(client);

    tg.join_all();
}

打印

sent: 12 bytes
length:12 data: [1,2,3]
sent: 120 bytes
length:120 data: { [1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15], [16,17,18], [19,20,21], [22,23,24], [25,26,27], [28,29,30],  }

對於非POD數據

您可以使用例如Boost Serialization來序列化數據

暫無
暫無

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

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