read/write方法windows
這些方法對一個流進行讀寫操做(可以是套接字,或者其它表現的像流的類):異步
async_read(stream, buffer [, completion],handler):這種方法異步地從一個流讀取。結束時,處理方法被調用。處理方法的格式是:void handler(const boost::system::error_ code & err, size_tbytes);。你可以選擇指定一個完畢處理方法。完畢處理方法會在每個read操做調用成功以後調用,而後告訴Boost.Asio async_read操做是否完畢(假設沒有完畢,它會繼續讀取)。它的格式是:size_t completion(const boost::system::error_code& err, size_tbytes_transfered) 。當這個完畢處理方法返回0時,咱們以爲read操做完畢;假設它返回一個非0值,它表示了下一個async_read_some操做需要從流中讀取的字節數。socket
接下來會有一個樣例來具體展現這些。async
async_write(stream, buffer [, completion],handler):這種方法異步地向一個流寫入數據。參數的意義和async_read是同樣的。tcp
read(stream, buffer [, completion]):這種方法同步地從一個流中讀取數據。參數的意義和async_read是同樣的。函數
rite(stream, buffer [, completion]): 這種方法同步地向一個流寫入數據。參數的意義和async_read是同樣的。命令行
° async_read(stream,stream_buffer [, completion], handler)code
° async_write(strean,stream_buffer [, completion], handler)繼承
° write(stream, stream_buffer[, completion])ip
° read(stream, stream_buffer[, completion])
首先,要注意第一個參數變成了流,而不單是socket。這個包括了socket但不不過socket。比方,你可以用一個Windows的文件句柄來替代socket。
當如下狀況出現時,所有read和write操做都會結束:
可用的緩衝區滿了(當讀取時)或者所有的緩衝區已經被寫入(當寫入時)。
完畢處理方法返回0(假設你提供了這麼一個方法)
發生錯誤時
如下的代碼會異步地從一個socket中間讀取數據直到讀取到’\n’:
io_service service;
ip::tcp::socket sock(service);
char buff[512];
size_t up_to_en
int offset = 0;
stem::error_code &, size_t bytes) {
ter(const boost::s
y
for( size_t i = 0; i < bytes; ++i)
if ( buff[i + offset] == '\n')
return 0;
return 1;
}
void on_read(const boost::system::error_code &, size_t) {}
...
c_read(sock, buffer(buff), up_to_enter,on_read);
asy
n
Boost.Asio也提供了一些簡單的完畢處理仿函數:
• transfer_at_least(n)
• transfer_exactly(n)
• transfer_all(
)
樣例例如如下:
char buff[512];
void on_read(constboost::system::error_code &, size_t) {}
// 讀取32個字節
async_read(sock, buffer(buff),transfer_exactly(32), on_read);
上述的4個方法,不使用普通的緩衝區,而使用由Boost.Asio的std::streambuf類繼承來的stream_buffer方法,stl流和流緩衝區很複雜;如下是樣例:
io_service service;
void on_read(streambuf& buf, constboost::system::error_code &,
size_t) {
std::istream in(&buf);
std::string line;
std::getline(in, line);
std::cout << "first line: "<< line << std::endl;
}
int main(int argc, char* argv[]) {
HANDLE file =::CreateFile("readme.txt", GENERIC_READ, 0, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
windows::stream_handle h(service, file);
streambuf buf;
uf, transfer_exactly(256),
async_read(h,
b
boost::bind(on_read,boost::ref(buf),_1,_2));
service.run();
}
在這裏,我向大家展現了在一個Windows文件句柄上調用async_read。咱們讀取了前面的256個字符,而後把它們保存到緩衝區,當操做結束時。on_read被調用,而後建立std::istream來傳遞緩衝區,讀取第一行(std::getline),最後把它輸出到命令行中。
read_until/async_read_until方法
這些方法在條件知足以前一直讀取:
async_read_until(stream, stream_buffer,delim, handler):這種方法啓動一個異步read操做。read操做會在讀取到某個分隔符時結束。分隔符可以是字符,std::string或者boost::regex。處理方法的格式爲:void handler(const boost::system::error_code & err, size_tbytes);。
async_read_until(strem, stream_buffer,completion, handler):這種方法和以前的方法是同樣的,但是沒有分隔符,而是一個完畢處理方法。完畢處理方法的格式爲:pair<iterator,bool> completion(iterator begin, iterator end);,當中迭代器的類型爲buffers_iterator<streambuf::const_buffers_type>。你需要記住的是迭代器的類型是隨機訪問的迭代器。你掃描整個區間(begin,end),而後認爲read操做是否應該結束。你會返回一個結果對,第一個成員是一個指向最後被這種方法訪問的字符的迭代器;第二個成員當read操做需要結束時返回true,不然返回false。
read_until(stream, stream_buffer, delim):這種方法運行一個同步的read操做,參數的意義和async_read_until同樣。
read_until(stream, stream_buffer,completion):這種方法運行一個同步的read操做,參數的意義和async_read_until同樣。
如下這個樣例會一直讀取直到讀到一個指定的標點符號
typedefbuffers_iterator<streambuf::const_buffers_type> iterator;
std::pair<iterator, bool>match_punct(iterator begin, iterator end) {
while ( begin != end)
if ( std::ispunct(*begin))
return std::make_pair(begin,true);
return std::make_pair(end,false);
}
void on_read(constboost::system::error_code &, size_t) {}
...
streambuf buf;
async_read_until(sock, buf, match_punct,on_read);
假設咱們想讀到一個空格結束,咱們需要把最後一行改動爲:
async_read_until(sock, buff, ' ', on_read);