Ứng dụng khách của tôi sử dụng boost::asio::ip::tcp::socket
để kết nối với máy chủ từ xa. Nếu ứng dụng mất kết nối với máy chủ này (ví dụ: do máy chủ gặp sự cố hoặc bị tắt), tôi muốn thử kết nối lại theo khoảng thời gian đều đặn cho đến khi ứng dụng thành công.Làm thế nào để tôi kết nối lại một cách hiệu quả boost :: socket sau khi ngắt kết nối?
Tôi cần làm gì ở phía máy khách để xử lý ngắt kết nối, dọn dẹp và sau đó liên tục thử kết nối lại?
Hiện tại, các bit thú vị của mã của tôi trông giống như thế này.
tôi connect
như thế này:
bool MyClient::myconnect()
{
bool isConnected = false;
// Attempt connection
socket.connect(server_endpoint, errorcode);
if (errorcode)
{
cerr << "Connection failed: " << errorcode.message() << endl;
mydisconnect();
}
else
{
isConnected = true;
// Connected so setup async read for an incoming message.
startReadMessage();
// And start the io_service_thread
io_service_thread = new boost::thread(
boost::bind(&MyClient::runIOService, this, boost::ref(io_service)));
}
return (isConnected)
}
Trường hợp phương pháp runIOServer()
chỉ là:
void MyClient::runIOService(boost::asio::io_service& io_service)
{
size_t executedCount = io_service.run();
cout << "io_service: " << executedCount << " handlers executed." << endl;
io_service.reset();
}
Và nếu bất kỳ của các bộ xử lý async đọc trả về một lỗi sau đó họ chỉ cần gọi phương thức disconnect
này:
void MyClient::mydisconnect(void)
{
boost::system::error_code errorcode;
if (socket.is_open())
{
// Boost documentation recommends calling shutdown first
// for "graceful" closing of socket.
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode)
{
cerr << "socket.shutdown error: " << errorcode.message() << endl;
}
socket.close(errorcode);
if (errorcode)
{
cerr << "socket.close error: " << errorcode.message() << endl;
}
// Notify the observer we have disconnected
myObserver->disconnected();
}
..những lần thử ngắt kết nối hoàn toàn và sau đó thông báo cho một người quan sát, sẽ bắt đầu gọi connect()
sau năm giây cho đến khi nó được kết nối lại.
Tôi còn cần phải làm gì khác không?
Hiện tại, điều này có nghĩa là dường như để hoạt động. Nếu tôi giết máy chủ mà nó được kết nối với tôi nhận được lỗi "End of file"
được mong đợi tại các trình xử lý đọc của tôi và mydisconnect()
được gọi mà không có bất kỳ vấn đề nào.
Nhưng khi nó cố gắng kết nối lại và không thành công, tôi thấy báo cáo "socket.shutdown error: Invalid argument"
. Đây có phải chỉ vì tôi đang cố gắng tắt một ổ cắm không có đọc/ghi đang chờ xử lý không? Hay là một cái gì đó nhiều hơn?
Lý do để gọi tắt máy của bạn là gì nếu bạn đã phát hiện đầu kia của kết nối bị đóng? –
@samm: Điều đó không được khuyến nghị? Tôi nghĩ rằng có thể có các hoạt động đang chờ xử lý trên socket cần được hủy bỏ bằng 'shutdown()'. Tôi chủ yếu chỉ làm điều đó để đơn giản mặc dù: cùng một phương thức 'mydisconnect()' được gọi nếu tôi muốn ngắt kết nối bình thường, hoặc nếu bất kỳ hoạt động async nào trả về lỗi. – GrahamS
Tôi không chắc chắn nó có được khuyên dùng hay không. Dữ liệu hoặc hoạt động đang chờ xử lý sẽ đi đâu? Đầu kia của kết nối không có ở đó. –