2009-10-02 41 views
14

Tôi muốn xác minh trạng thái kết nối trước khi nhận ra các hoạt động của mình (đọc/ghi).boost :: asio :: ip :: tcp :: socket được kết nối?

Có cách nào để tạo phương thức isConnect() không?

Tôi thấy this, nhưng có vẻ như "xấu xí".

Tôi đã thử nghiệm chức năng is_open(), nhưng không có hành vi mong muốn.

+0

bản sao có thể có của [Cách kiểm tra xem ổ cắm có được đóng trong Boost.Asio không?] (Http://stackoverflow.com/questions/818665/how-to-check-if-socket-is-closed-in-boost -asio) – joshperry

Trả lời

28

TCP có nghĩa là để được mạnh mẽ khi đối mặt với một mạng lưới khắc nghiệt; mặc dù TCP cung cấp những gì trông giống như một kết nối end-to-end liên tục, tất cả chỉ là một lời nói dối, mỗi gói thực sự chỉ là một datagram duy nhất, không đáng tin cậy.

Các kết nối thực sự chỉ là ống dẫn ảo được tạo với trạng thái nhỏ được theo dõi ở mỗi đầu của kết nối (cổng nguồn và đích và địa chỉ và ổ cắm cục bộ). Ngăn xếp mạng sử dụng trạng thái này để biết quy trình nào cung cấp cho mỗi gói đến và trạng thái nào được đặt trong tiêu đề của mỗi gói gửi đi.

Virtual TCP Conduit

Do tiềm ẩn — vốn phi kết nối và không đáng tin cậy — bản chất của mạng, ngăn xếp sẽ chỉ báo cáo một kết nối bị cắt đứt khi kết thúc từ xa gửi một gói tin FIN để đóng kết nối, hoặc nếu nó doesn' t nhận được một phản ứng ACK cho một gói tin gửi đi (sau một thời gian chờ và một vài lần thử lại).

Do tính chất không đồng bộ của asio, cách dễ nhất để được thông báo về ngắt kết nối duyên dáng là có số async_read nổi bật sẽ trả lại error::eof ngay lập tức khi kết nối bị đóng. Nhưng điều này một mình vẫn còn khả năng của các vấn đề khác như kết nối một nửa mở và các vấn đề mạng sẽ không bị phát hiện.

Cách hiệu quả nhất để làm việc xung quanh gián đoạn kết nối không mong muốn là sử dụng một số loại giữ nguyên hoặc ping. Điều này thường xuyên cố gắng để chuyển dữ liệu qua kết nối sẽ cho phép phát hiện đúng đắn của một kết nối vô tình bị cắt đứt.

Giao thức TCP thực sự có tích hợp keep-alive mechanism có thể được định cấu hình bằng asio sử dụng asio::tcp::socket::keep_alive. Điều tuyệt vời về TCP keep-alive là nó trong suốt đối với ứng dụng chế độ người dùng, và chỉ những đồng nghiệp quan tâm đến việc giữ cho nó luôn cần cấu hình nó. Nhược điểm là bạn cần truy cập/kiến ​​thức ở mức hệ điều hành để cấu hình các tham số thời gian chờ, chúng không được tiếp xúc thông qua tùy chọn socket đơn giản và thường có giá trị timeout mặc định khá lớn (7200 giây trên Linux).

Có lẽ phương pháp phổ biến nhất để giữ sống là triển khai nó ở lớp ứng dụng, trong đó ứng dụng có thông báo ping hoặc ping đặc biệt và không làm gì ngoài phản hồi khi bị cù. Phương pháp này mang đến cho bạn sự linh hoạt nhất trong việc thực hiện chiến lược tiếp tục sống.

+0

Có một vấn đề với chương trình không hoạt động: Tôi không có quyền truy cập vào máy chủ nơi ứng dụng sẽ chạy, do đó tôi không thể thay đổi thời gian chờ giữ (7200 giây tại đây). Nhưng tôi thích phản ứng này, vì vậy nếu tôi cần điều này một lần nữa, tôi sẽ kích hoạt TCP keel-alive. Cảm ơn – coelhudo

+0

Tôi quên nói những gì tôi đã làm, tôi chỉ cố gắng đọc/ghi, kiểm tra lỗi và đưa ra quyết định dựa trên lỗi này. – coelhudo

+0

Hình ảnh không xuất hiện nữa, bạn có thể sửa lỗi này không? Tôi muốn xem hình minh họa. Cảm ơn. – coelhudo

0

bạn có thể gửi byte giả trên ổ cắm và xem nó có trả về lỗi hay không.

+3

Nhưng điều gì xảy ra với đầu kia khi nó nhận byte giả này nếu bạn được kết nối. Đó không phải là một giải pháp tốt. – jmucchiello

+2

Thông thường loại ứng dụng này có khái niệm về nhịp tim gửi định kỳ. Hơn nữa, trên các cửa sổ (win32) không có cách nào để kiểm tra kết nối một cách đáng tin cậy, và tăng thêm :: asio :: ip :: tcp :: socket sẽ được thực hiện trên đầu trang của nó. @jmucchiello - nếu bạn đã từng làm việc trên một hệ thống phân tán, bạn sẽ biết rằng kết nối luôn được kiểm tra qua nhịp tim, thường là một byte. Hy vọng điều này sẽ giúp OP. – vehomzzz

+0

Có một vấn đề, tôi không biết hành vi ở phía máy chủ. Giải pháp mà tôi tìm thấy, là kết nối cuộc gọi trước khi vận hành và kiểm tra tình trạng lỗi. – coelhudo

1

TCP hứa hẹn sẽ xem các gói bị xóa - thử lại khi thích hợp - để cung cấp cho bạn kết nối đáng tin cậy, đối với một số định nghĩa đáng tin cậy. Tất nhiên TCP không thể xử lý các trường hợp xảy ra sự cố máy chủ hoặc cáp Ethernet của bạn bị trục trặc hoặc xảy ra sự cố tương tự. Ngoài ra, biết rằng kết nối TCP của bạn không nhất thiết có nghĩa là một giao thức sẽ đi qua kết nối TCP đã sẵn sàng (ví dụ, máy chủ web HTTP của bạn hoặc máy chủ FTP của bạn có thể ở trạng thái bị hỏng).

Nếu bạn biết giao thức được gửi qua TCP sau đó có lẽ là một cách trong giao thức đó để cho bạn biết nếu điều này là trong tình trạng tốt (cho HTTP nó sẽ là một HEAD request)

Các vấn đề liên quan