Tôi đang phát triển một máy chủ trong C# chỉ có thể chấp nhận một ứng dụng khách và tôi cần biết khi nào máy khách này bị ngắt kết nối để có thể chấp nhận một yêu cầu kết nối khác.Thực tiễn tốt nhất để phát hiện ngắt kết nối máy khách trong .NET?
Tôi đang sử dụng Ổ cắm đầu tiên liên tục nghe yêu cầu kết nối với Socket.BeginAccept
và chấp nhận hoặc từ chối khách hàng. Khi một máy khách được chấp nhận, Socket mới được trả về bởi Socket.EndAccept
được sử dụng cho giao tiếp giữa máy khách và máy chủ. Sau đó, máy chủ chờ các lệnh từ máy khách với Socket.Begin/EndReceive
và gửi câu trả lời. Máy chủ sử dụng giao thức giống như Telnet, có nghĩa là mỗi lệnh và mỗi dòng phản hồi phải kết thúc bằng \r\n
.
Để phát hiện xem máy khách đã bị ngắt kết nối chưa, tôi đã cài đặt bộ hẹn giờ gửi mỗi 500ms một thông báo trống ("\r\n
") đến máy khách. Nếu khách hàng bị ngắt kết nối, một ngoại lệ được ném bởi Socket. Ngoại lệ này bị máy chủ chặn phải đóng phiên hiện tại và chấp nhận kết nối mới. Giải pháp này là mạnh mẽ nhưng ngụ ý lưu lượng truy cập không cần thiết qua mạng và phải được xử lý chính xác bởi ứng dụng khách phải lọc các thông điệp giả trước khi nhận được phản hồi thực tế.
Tôi đã cố gắng gửi bộ đệm trống (Socket.Send(new byte[1], 0, 0)
), nhưng có vẻ như không hoạt động theo hướng máy chủ-> máy khách.
Một giải pháp khác có thể là xử lý trường hợp trong đó Socket.EndReceive
trả về 0 byte. Nó hoạt động tốt cho trường hợp ngắt kết nối xảy ra trong thời gian "nhàn rỗi". Nhưng nếu khách hàng ngắt kết nối trong quá trình chuyển thư, máy chủ không phải lúc nào cũng thấy và chờ vô thời hạn.
Tôi đã xem một số chủ đề và câu hỏi về vấn đề này, nhưng tôi chưa bao giờ thấy bất kỳ giải pháp tốt nào.
Vì vậy, câu hỏi của tôi là: cách tốt nhất để phát hiện ngắt kết nối trong .Net là gì?
OK, tôi đã thêm mã bật KeepAlive cho ổ cắm của tôi. Nhưng tôi nghĩ điều gì sẽ xảy ra? Không có gì xảy ra khi khách hàng ngắt kết nối ... Tôi dự kiến sẽ nhận được một Ngoại lệ ở đâu đó ... Tôi có nên đọc hoặc viết một cái gì đó định kỳ không? – cedrou
Tôi mặc dù bạn đang sử dụng Begin/EndReceive? Nếu vậy, BeginReceive sẽ chạy gọi lại và khi bạn gọi EndReceive để có được kết quả một ngoại lệ nên được nâng lên, đó hoặc một kết thúc của dòng 0 byte đọc. –
OK, bây giờ tôi có ngoại lệ ... Cảm ơn – cedrou