2012-03-29 13 views
6

Tôi đang sử dụng Boost :: asio để triển khai ứng dụng khách/máy chủ. Mã máy khách bên dưới được sử dụng để kết nối với máy chủ từ xa.Làm cách nào để kiểm tra xem kết nối ổ cắm có hoạt động trong Boost :: asio không?

try 
    { 
     boost::asio::io_service   m_io_service; 
     boost::asio::ip::tcp::socket m_socket(m_io_service); 
     boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 17); 
     m_socket.connect(endpoint); 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 

Ở phía khách hàng, tôi muốn kiểm tra xem kết nối có đang hoạt động hay không. Chức năng "m_socket.is_open();" không hoạt động. Khi đóng socket máy chủ, "m_socket.is_open();" vẫn trả về true ở phía máy khách. Có cách nào để kiểm tra kết nối không?

+1

Tôi có một sự nghi ngờ tương tự ở đây: http://stackoverflow.com/q/1511129/174605 và có câu trả lời hay bằng cách joshperry – coelhudo

Trả lời

2

Do giới hạn của giao diện ổ cắm bên dưới, không có cách nào để thực hiện chức năng như được kết nối để kiểm tra trạng thái kết nối TCP ở mức ổ cắm. Tôi nghĩ ra một cách giải quyết khác.

Trong quá trình triển khai, tôi lưu vào bộ nhớ cache cờ trạng thái kết nối (bool m_IsConnected) trong ứng dụng của mình. Cờ này được sử dụng để chỉ định trạng thái kết nối. Nó giả định rằng nếu không có lỗi từ socket, kết nối TCP vẫn còn hoạt động.

Cờ sẽ được cập nhật mỗi khi sử dụng ổ cắm. Nếu có lỗi khi gửi và đọc dữ liệu, điều đó có nghĩa là kết nối bị ngắt kết nối. Sau đó thay đổi cờ tương ứng. Nếu kết nối TCP không hoạt động trong một thời gian dài. Cờ này không phản ánh tình trạng thực tế của kết nối TCP cho đến khi sử dụng socket. Ví dụ, ổ cắm không hoạt động trong một thời gian dài. Nó bị ngắt kết nối do mạng kém. Trong trường hợp này, m_IsConnected vẫn đúng vì chúng ta không nhận được bất kỳ cuộc gọi lại nào về sự kiện ngắt kết nối. Khi cố gắng gửi dữ liệu qua ổ cắm này, sẽ có lỗi. Và bây giờ chúng ta biết rằng kết nối bị ngắt kết nối.

0

Đây là giới hạn của giao diện ổ cắm bên dưới (tôi nghĩ cả cho Winsock/Bekerly). Bạn có thể phát minh ra một thông điệp đặc biệt cho mục đích này, rằng máy chủ trả lời nếu nó còn sống. Khác nếu bạn nhận được một thời gian chờ, có nghĩa là kết nối là xuống.

EDIT: Như Joachim đã chỉ ra, cố gắng đọc ổ cắm có thể là một cách tốt hơn.

+3

Đang cố gắng gửi tới kết nối đã bị đóng sẽ đưa ra lỗi, ngay cả khi đó là một đóng cửa sạch sẽ và phù hợp. Việc cố gắng _read_ từ socket sẽ cung cấp một đầu mối tốt hơn về cách đóng socket (tức là 'read' hoặc' recv' trả về 0 cho một đóng sạch hoặc lỗi khi có lỗi.) –

+0

Ah vâng bạn đúng, tôi Quên bạn cũng có thể đọc nó. Sẽ cập nhật câu trả lời ở trên. – Rolle

+0

Chức năng tăng cường miễn phí :: asio :: đọc có thể được sử dụng để đọc ổ cắm. Tôi nghĩ rằng có tác dụng phụ nếu sử dụng chức năng đọc phát hiện tình trạng kết nối. Nó sẽ đọc dữ liệu từ luồng socket, mà tôi không muốn trong chức năng phát hiện trạng thái. Hơn nữa, nếu kết nối còn sống, khối chức năng đọc sẽ bị khóa. – Jeffrey