2010-03-31 39 views
16

Ở phía máy khách, tôi cần biết khi nào/nếu kết nối ổ cắm của tôi bị hỏng. Tuy nhiên, thuộc tính Socket.Connected luôn trả về true, ngay cả sau khi phía máy chủ bị ngắt kết nối và tôi đã thử gửi dữ liệu qua nó. Bất cứ ai có thể giúp tôi tìm ra những gì đang xảy ra ở đây. Tôi cần biết khi nào một ổ cắm đã bị ngắt kết nối.Làm thế nào để biết khi nào một Ổ cắm đã bị ngắt kết nối

 Socket serverSocket = null; 
     TcpListener listener = new TcpListener(1530); 
     listener.Start(); 
     listener.BeginAcceptSocket(new AsyncCallback(delegate(IAsyncResult result) 
     { 
      Debug.WriteLine("ACCEPTING SOCKET CONNECTION"); 
      TcpListener currentListener = (TcpListener)result.AsyncState; 
      serverSocket = currentListener.EndAcceptSocket(result); 
     }), listener); 


     Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, and it is 
     clientSocket.Connect("localhost", 1530); 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be TRUE, and it is 

     Thread.Sleep(1000); 
     serverSocket.Close();//closing the server socket here 
     Thread.Sleep(1000); 

     clientSocket.Send(new byte[0]);//sending data should cause the socket to update its Connected property. 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, but its always TRUE 
+0

Xem http://stackoverflow.com/questions/722240/instantly-detect-client-disconnection-from-server-socket để thảo luận thêm. – EricLaw

Trả lời

0

làm phương thức clientSocket.Send

Nếu không mã của bạn đang bay lên dòng tiếp theo trong khi ổ cắm vẫn đang cố gắng tìm ra những gì đang diễn ra.

+0

Bạn có thể đặt một Thread.Sleep sau khi gửi. Không có vấn đề bao lâu bạn chờ đợi clientSocket.Connected vẫn đúng sự thật. – BowserKingKoopa

9

Sau khi thực hiện một số thử nghiệm, có vẻ tài liệu cho Socket.Connected là sai hoặc ít gây hiểu lầm nhất. clientSocket.Connected sẽ chỉ trở thành sai sau clientSocket.close() được gọi. Tôi nghĩ rằng đây là một sự trở lại với API socket S Berkeley ban đầu và thuật ngữ của nó. Một socket bị ràng buộc khi nó có một địa chỉ cục bộ liên kết với nó, và một socket được kết nối khi nó có một địa chỉ từ xa được kết hợp với nó. Mặc dù phía xa đã đóng kết nối, ổ cắm cục bộ vẫn có liên kết và do đó nó vẫn "kết nối".

Tuy nhiên, đây là một phương pháp mà không công việc:

!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0) 

Nó dựa trên thực tế rằng một kết nối khép kín sẽ được đánh dấu là có thể đọc được mặc dù không có dữ liệu có sẵn.

Nếu bạn muốn phát hiện các điều kiện như cáp mạng bị hỏng hoặc máy tính đột ngột bị tắt, tình hình phức tạp hơn một chút. Trong những điều kiện đó, máy tính của bạn không bao giờ nhận được một gói cho biết rằng ổ cắm đã đóng. Nó cần phải phát hiện rằng phía xa đã biến mất bằng cách gửi các gói tin và nhận thấy rằng không có phản hồi nào trở lại. Bạn có thể làm điều này ở cấp ứng dụng như là một phần của giao thức của bạn, hoặc bạn có thể sử dụng tùy chọn TCP KeepAlive. Sử dụng TCP Keep Alive từ .NET không phải là dễ dàng; bạn có thể tốt hơn việc xây dựng một cơ chế tiếp tục trong giao thức của bạn (thay vào đó, bạn có thể đặt một câu hỏi riêng cho "Làm thế nào để kích hoạt tính năng TCP Keep Alive trong .NET và thiết lập khoảng thời gian còn lại?").

+0

socket.Poll (0, SelectMode.SelectRead) luôn trả về true cho tôi ngay cả sau khi kết nối phía máy chủ đã bị đóng. – BowserKingKoopa

+0

Ngoài ra các tài liệu msdn nói rằng phương pháp thăm dò ý kiến ​​không thể phát hiện các điều kiện nhất định "chẳng hạn như một cáp mạng bị hỏng, hoặc máy chủ từ xa đã tắt không đúng lúc". Tôi chỉ muốn biết nếu ổ cắm phía máy chủ là có hay không, tôi không quan tâm lý do tại sao nó không có. – BowserKingKoopa

+0

@BrowserKingKoopa: Rất tiếc! Mã tôi đăng đầu tiên được kiểm tra rằng ổ cắm là * ngắt kết nối *. Tôi đã sửa nó. Khi phía xa đã ngắt kết nối, Thăm dò ý kiến ​​() sẽ trả về true nhưng socket. Có sẵn sẽ là 0. Tôi cũng đã thêm một đoạn về xử lý các cáp mạng bị hỏng. –

3

Có thể giải pháp là gửi một số dữ liệu giả qua nó và kiểm tra xem nó có hết thời gian không?

2

Tôi khuyên bạn nên loại bỏ nội dung ngôn ngữ cấp cao hơn và khám phá điều gì xảy ra ở mức IO thấp hơn.

Thấp nhất tôi đã khám phá trong khi viết isectd (tìm trên sourceforge). Sử dụng lệnh gọi hệ thống select(), một bộ mô tả cho một socket khép kín trở thành sẵn sàng đọc, và khi isectd sẽ cố gắng recv() trạng thái ngắt kết nối của socket có thể được xác nhận.

Là giải pháp, tôi khuyên bạn không nên ghi IO socket của riêng mình và sử dụng phần mềm trung gian của người khác. Có rất nhiều ứng cử viên giỏi ngoài kia. Đừng quên xem xét các dịch vụ xếp hàng đơn giản.

PS. Tôi đã cung cấp URL cho tất cả những điều trên nhưng danh tiếng của tôi (1) không cho phép.

4

Chỉ cần ghi vào ổ cắm của bạn như bình thường. Bạn sẽ biết khi nào nó bị ngắt kết nối bởi Ngoại lệ cho biết dữ liệu của bạn không thể được gửi.

Nếu bạn không có gì để viết ... thì ai quan tâm nếu nó bị ngắt kết nối? Nó có thể bị ngắt kết nối ngay bây giờ, nhưng quay trở lại trước khi bạn cần nó - tại sao làm phiền nó rách xuống, và sau đó lặp lại một kết nối lại cho đến khi liên kết được sửa chữa ...đặc biệt là khi bạn không có bất cứ điều gì để nói anyway?

Nếu nó làm phiền bạn, hãy thực hiện việc duy trì hoạt động trong giao thức của bạn. Sau đó, bạn sẽ có một cái gì đó để nói mỗi 30 giây hoặc lâu hơn.

+0

+1 nếu máy chủ gửi tất cả dữ liệu và nó không hoạt động, nó sẽ đóng socket và client nên xử lý nó một cách thích hợp. từ phía khách hàng nếu nó nhận được tất cả dữ liệu nó muốn nó chỉ đóng kết nối quá, máy chủ sẽ xử lý nó. bạn chỉ cần bắt ngoại lệ trên s.Receive/s.Để biết khi nào ai đó bị ngắt kết nối, Thăm dò ý kiến ​​cũng sẽ ném ngoại lệ trên ổ cắm bị ngắt kết nối – hoodoos

+0

Ổ cắm hoạt động cả hai cách, vấn đề chính là khi bạn sử dụng đẩy bằng cách sử dụng ổ cắm. d/c mà bạn không biết nó để bạn không nhận được dữ liệu khi đọc luồng mạng cung cấp cho dữ liệu nhưng không có lỗi. –

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