如果 boost::asio::socket 的缓冲区中有一些数据,我该如何读取?检查应该阻止程序的执行,直到达到超时。我发现可以使用该功能
boost::asio::socket_base::bytes_readable
但似乎是一个非阻塞操作,无需检查任何超时即可运行。我不想使用 async_read 但如果有一些数据要读取,则直接读取套接字
如果 boost::asio::socket 的缓冲区中有一些数据,我该如何读取?检查应该阻止程序的执行,直到达到超时。我发现可以使用该功能
boost::asio::socket_base::bytes_readable
但似乎是一个非阻塞操作,无需检查任何超时即可运行。我不想使用 async_read 但如果有一些数据要读取,则直接读取套接字
您只需使该套接字变为非阻塞并等待套接字准备好读取或使用事件循环超时。
阻止程序执行等待套接字中的某些字节的一种简单方法是将函数置于监视经过时间的 while 循环中。下面是一个简单的解决方案,它将:
int find_char(char* buffer, size_t size_out, char chr)
#include <boost/asio.hpp>
int main () {
const int MAX_BUFFER_SIZE = 1024; //max size of buffer
const char PACKET_END = static_cast<char>(0xFF); //character that identifies the end of a packet
//creation of Client Socket
boost::asio::io_service ios;
boost::asio::ip::tcp::socket client_socket(ios);
//creation of endpoint connection
std::string host_ip = "199.01.00.00";
int port_number = 2000;
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(host_ip), port_number);
//connect client socket to server
boost::system::error_code error_connection; //connection error
//conect to server
bool is_connected = false;
client_socket.connect(endpoint, error_connection);
if(!error_connection)
is_connected = true;
//read from server buffer
if (is_connected == true) { //connected
//create empty buffer to store from server
char buffer[MAX_BUFFER_SIZE];
std::fill(buffer, buffer + sizeof(buffer), 0);
//TCPIP read from buffer
boost::system::error_code error_read;
//initialize Timeout variables
int timeout = 5000000; //timeout of 5 seconds [microsec]
boost::posix_time::time_duration difference; //elapsed time
boost::posix_time::time_duration time_to_read; //duration of reading
boost::posix_time::ptime start_try_read = boost::posix_time::microsec_clock::local_time(); //save initial time to read
//understand if there is something to read
size_t bytes_readable = 0;
bool something_to_read = false; //check if something to read
do {
boost::posix_time::ptime start_read = boost::posix_time::microsec_clock::local_time(); //save initial time to try read
boost::asio::socket_base::bytes_readable num_bytes_readable(true);
client_socket.io_control(num_bytes_readable, error_read);
bytes_readable = num_bytes_readable.get(); //get the value of readable data
if ( bytes_readable > 0 ){
//found something to read
something_to_read = true;
break;
}
if (error_read == boost::asio::error::not_connected){
//server disconnected
is_connected = false;
something_to_read = false;
break;
}
boost::posix_time::ptime end_read = boost::posix_time::microsec_clock::local_time(); //save final time to try read
time_to_read = end_read - start_read;
difference = end_read - start_try_read;
} while ( difference + time_to_read < boost::posix_time::microsec(time_out) && bytes_readable <= 0 );
if (is_connected == true && difference + time_to_read >= boost::posix_time::microsec(time_out)) {
//nothing to read, timeout
something_to_read = false;
}
else if (is_connected == true && !error_read && bytes_readable > 0) {
//prepare to store the buffer
char buffer_socket[bytes_readable + 1];
std::fill(buffer_socket, buffer_socket + sizeof(buffer_socket), 0);
//read from buffer the readable bytes amount and store
boost::asio::read(client_socket, boost::asio::buffer(buffer_socket, bytes_readable));
//check if message contains special character
int position_end = find_char(buffer_socket, sizeof(buffer_socket), static_cast<char>(PACKET_END));
//in case found an interesting message, reply to server
if (position_end >= 0){
std::memcpy(buffer, buffer_socket, position_end + 1); //found interesting message, store it
//write response to server socket
char response[100] = "received good message";
boost::system::error_code error_write;
boost::asio::write(client_socket, boost::asio::buffer((char*)ct_request_buffer, sizeof(ct_request_buffer)), error_write);
}
}
}
}
int find_char(char* buffer, size_t size_out, char chr){
int pos = -1;
size_t i = size_out - 1;
while (i >= 0){
if (buffer[i] == chr){
pos = i;
break;
}
i--;
}return pos;
}