Один простой способ заблокировать выполнение программы, ожидающей несколько байтов в сокете, - поместить функцию в цикл while, который контролирует истекшее время.Ниже приведено простое решение, которое будет:
- подключаться к серверу
- читать с сервера.Если нечего читать, подождите до истечения времени ожидания
- , проверьте сообщение сервера и ответьте
int find_char (char * буфер, 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;
}