該程式將演示如何將乙個簡單結構序列化後傳送到網路上,如何從網路上接收到資料後反序列化回結構。
建立連線
首先使用ace_sock_connector::connect連線某個伺服器(使用ip位址和埠號),該伺服器上使用ace_sock_acceptor::accept等待外部的連線請求。
ace_inet_addr類進行管理socket通訊使用的ip位址和埠號。
當連線建立的時候,連線者和等待者都初始化乙個傳輸者用於通訊。
下面就是連線者如何連線本機的7777埠的服務程式**:
#include using namespace std;
#include "ace/inet_addr.h"
#include "ace/sock_stream.h"
#include "ace/sock_connector.h"
int main(void)
ace_uint16 type_;
ace_uint32 offset_;
void* pdata_;
ace_uint32 datalength_;
size_t size() const
~shmrecord()
};int operator<<(ace_outputcdr & cdr,shmrecord const& record)
int operator>>(ace_inputcdr & cdr,shmrecord & record)
int main(void)
{ace_inet_addr address("127.0.0.1:7777");
ace_sock_connector connector;
ace_sock_stream stream;
if(connector.connect(stream,address)==-1)
{cout<(record.pdata_),"hih");
const size_t size=record.size()+ace_cdr::max_alignment;
ace_outputcdr payload(size);
payloadiov[0].iov_len=8;
iov[1].iov_base=payload.begin()->rd_ptr();
iov[1].iov_len=size;
stream.sendv_n(iov,2);
cout<(record.pdata_)<
ace提供了ace_outputcdr和ace_inputcdr類,是針對網路程式經常遇到的將物件資料序列化到位元組流和從位元組流中反序列化到物件的情況。你可以提供自己的operator《和operator>>操作,就像上面的例子一樣。
這種方式和支援標準c++流的方式是一樣的。那麼,為什麼不直接使用標準c++流呢?因為ace所支援的平台很多,有些編譯器不支援標準c++流。並且據我個人的體驗,標準c++流在記憶體管理上是封裝的,你不可能通過公有方法獲得內部關裡的緩衝區的指標,除非自己定義自己的派生類,這並不容易。還有乙個原因是不同編譯器和不同的硬體使用了不同的位元組對齊方式(大尾數法和小尾數法)。使用ace的cdr類就可以保證各種環境下都能使用,因為它在內部使用了corba公共資料表示的格式。
對於基本的數值型別,各個平台也有可能有長度的差異,比如int究竟是16,32還是64。所以這裡使用了ace提供的基本數值型別,比如ace_uint32。
在這個示例程式裡,我們實際上建立了兩個ace_outputcdr物件,乙個用來表示資料頭,乙個存發實際結構中的資料。資料頭中前4個位元組存放了乙個布林值,表示本機的位元組順序,後面四個位元組表示第二個物件的實際長度。
因此,接收資料時首先接收固定長度的頭物件,取得位元組順序標誌後,調整位元組順序,然後獲取實際長度,根據該長度接收第二個ace_outputcdr物件存放的實際資料。
下面的例子演示了如何接收傳送來的資料。
int main(void)
{ ace_sock_acceptor acceptor;
ace_inet_addr address;
address.set(7777);
if(acceptor.open(address)==-1)
{coutace_cdr::mb_align(spblock.get());
if(stream.recv_n(spblock->wr_ptr(),8)==8)//receive the header of cdr
{//parse the cdr header
spblock->wr_ptr(8);
ace_inputcdr cdr(spblock.get());
ace_cdr::boolean byte_order;
cdr>>ace_inputcdr::to_boolean(byte_order);
cdr.reset_byte_order(byte_order);
ace_cdr::ulong length;
cdr>>length;
//receive the data from master
spblock->size(length+8+ace_cdr::max_alignment);
if(stream.recv_n(spblock->wr_ptr(),length)==length)
{spblock->wr_ptr(length);
//必須重新建立乙個cdr物件,否則解析不正確
ace_inputcdr cdr2(spblock.get());
ace_cdr::boolean byte_order;
cdr2>>ace_inputcdr::to_boolean(byte_order);
cdr2.reset_byte_order(byte_order);
ace_cdr::ulong length;
cdr2>>length;
auto_ptrsprecord(new shmrecord);
cdr2>>*sprecord;
coutpdata_)在上面的例子中,我們 建立了乙個預設大小的ace_message_block物件,然後將接收的資料寫入ace_data_block的緩衝區中,並且移動寫指標的位置。ace_inputcdr通過和ace_message_block物件關聯來讀取緩衝區的資料。
用ACE開發網路通訊程式
該程式將演示如何將乙個簡單結構序列化後傳送到網路上,如何從網路上接收到資料後反序列化回結構。首先使用ace sock connector connect連線某個伺服器 使用ip位址和埠號 該伺服器上使用ace sock acceptor accept等待外部的連線請求。ace inet addr類進...
Winsock開發網路通訊程式的經典入門
對於許多初學者來說,網路通訊程式的開發,普遍的乙個現象就是覺得難以入手。許多概念,諸如 同步 sync 非同步 async 阻塞 block 非阻塞 unblock 等,初學者往往迷惑不清,只知其所以而不知起所以然。同步方式指的是傳送方不等接收方響應,便接著發下個資料報的通訊方式 而非同步指傳送方發...
Winsock開發網路通訊程式的經典入門
對於許多初學者來說,網路通訊程式的開發,普遍的 乙個現象就是覺得難以入手。許多概念,諸如 同步 sync 非同步 async 阻塞 block 非阻塞 unblock 等,初學者往往迷惑不清,只知其所以而不知起所以然。同步方式指的是傳送方不等接收方響應,便接著發下 個資料報的通訊方式 而非同步指傳送...