Tôi có cùng một câu hỏi, và sau khi một số nghiên cứu, giải pháp đơn giản nhất, sạch nhất mà tôi có thể đưa ra là để có được những cơ bản ổ cắm gốc và thực hiện lựa chọn cho đến khi có dữ liệu để đọc. Chọn sẽ mất một tham số thời gian chờ. Tất nhiên, làm việc với ổ cắm bản địa bắt đầu đi ngược lại điểm sử dụng asio ngay từ đầu, nhưng một lần nữa, điều này có vẻ là cách sạch nhất. Theo như tôi có thể nói, asio không cung cấp một cách để làm điều này để sử dụng đồng bộ một cách dễ dàng. Mã số:
// socket here is: boost::shared_ptr<boost::asio::ip::tcp::socket> a_socket_ptr
// Set up a timed select call, so we can handle timeout cases.
fd_set fileDescriptorSet;
struct timeval timeStruct;
// set the timeout to 30 seconds
timeStruct.tv_sec = 30;
timeStruct.tv_usec = 0;
FD_ZERO(&fileDescriptorSet);
// We'll need to get the underlying native socket for this select call, in order
// to add a simple timeout on the read:
int nativeSocket = a_socket_ptr->native();
FD_SET(nativeSocket,&fileDescriptorSet);
select(nativeSocket+1,&fileDescriptorSet,NULL,NULL,&timeStruct);
if(!FD_ISSET(nativeSocket,&fileDescriptorSet)){ // timeout
std::string sMsg("TIMEOUT on read client data. Client IP: ");
sMsg.append(a_socket_ptr->remote_endpoint().address().to_string());
throw MyException(sMsg);
}
// now we know there's something to read, so read
boost::system::error_code error;
size_t iBytesRead = a_socket_ptr->read_some(boost::asio::buffer(myVector), error);
...
Có lẽ điều này sẽ hữu ích cho trường hợp của bạn.
Nguồn
2011-04-20 18:43:43
Đây sẽ là một giải pháp tuyệt vời, nhưng chúng không có các tùy chọn ổ cắm như vậy. Xem các tùy chọn ổ cắm tại đây: http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/reference.html –
Tăng cường tốt nhưng không hoàn hảo :-) –
Nhưng từ những gì tôi có thể nói, read_some của asio() sẽ vẫn tiếp tục nội bộ lặp mãi mãi nếu nó không đọc gì, do đó hủy bỏ hiệu quả của SO_RCVTIMEO bạn có thể đã đặt trên ổ cắm gốc. Hình như sử dụng select() với socket.native() sẽ vẫn là cách rõ ràng nhất để có thời gian chờ. –