Creating a simple TCP server based on examples but still do not get how to create a socket that would read some amount of bytes and if there will not be enough would wait. I need this to be NOT asynchronous operation.
#include <iostream>
#include <boost/asio.hpp>
#ifdef _WIN32
#include "Windows.h"
#endif
using namespace boost::asio::ip;
using namespace std;
int main(){
int m_nPort = 12345;
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort));
cout << "Waiting for connection..." << endl;
tcp::socket socket(io_service);
acceptor.accept(socket);
cout << "connection accepted" << endl;
try
{开发者_开发百科
socket.send(boost::asio::buffer("Start sending me data\r\n"));
}
catch(exception &e)
{
cerr << e.what() << endl; //"The parameter is incorrect" exception
}
}
How to receive 10000 bytes and do it either until all 10000 arrive OR 1000 millisecond timeout and throw an exception?
Boost 1.47.0 just introduced a timeout feature for basic_socket_iostream
, namely, the expires_at
and expires_from_now
methods.
Here's an example based on your snippet:
#include <iostream>
#include <boost/asio.hpp>
using namespace boost::asio::ip;
using namespace std;
int main(){
int m_nPort = 12345;
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort));
cout << "Waiting for connection..." << endl;
tcp::iostream stream;
acceptor.accept(*stream.rdbuf());
cout << "Connection accepted" << endl;
try
{
stream << "Start sending me data\r\n";
// Set timeout in 5 seconds from now
stream.expires_from_now(boost::posix_time::seconds(5));
// Try to read 12 bytes before timeout
char buffer[12];
stream.read(buffer, 12);
// Print buffer if fully received
if (stream) // false if read timed out or other error
{
cout.write(buffer, 12);
cout << endl;
}
}
catch(exception &e)
{
cerr << e.what() << endl;
}
}
This program works for me on Linux.
Please note that I'm not advocating that you use timeouts instead of asynchronous operation with a deadline timer. It's up to you to decide. I just wanted to show that timeouts are possible with basic_socket_iostream
.
How to timeout and throw an exception?
Generally speaking, you only get timeouts and cancelability when using asynchronous methods. There are some platform specific ways around this, which have been discussed on SO in previous questions. I strongly suggest you investigate using asynchronous methods, it will make understanding the logic much easier.
That said, you can present a synchronous interface by using asynchronous methods underneath. This is done in the blocking TCP client timeout example provided by the Asio library. Beware however, the example isn't entirely straightforward (albeit, well commented) due to its inversion of control and use of lambda functions. I suggest you investigate using asynchronous methods directly prior to attempting something like this.
How to receive 10000 bytes?
use the async_read
free function, the remarks section describes exactly what you need
Remarks
This overload is equivalent to calling:
boost::asio::async_read( s, buffers, boost::asio::transfer_all(), handler);
where your buffer is 10,000 bytes in size.
精彩评论