2008-09-30 30 views

Trả lời

59

Phương pháp isConnected sẽ không hỗ trợ, nó sẽ trả lại true ngay cả khi mặt từ xa đã đóng ổ cắm. Hãy thử điều này:

public class MyServer { 
    public static final int PORT = 12345; 
    public static void main(String[] args) throws IOException, InterruptedException { 
     ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(PORT); 
     Socket s = ss.accept(); 
     Thread.sleep(5000); 
     ss.close(); 
     s.close(); 
    } 
} 

public class MyClient { 
    public static void main(String[] args) throws IOException, InterruptedException { 
     Socket s = SocketFactory.getDefault().createSocket("localhost", MyServer.PORT); 
     System.out.println(" connected: " + s.isConnected()); 
     Thread.sleep(10000); 
     System.out.println(" connected: " + s.isConnected()); 
    } 
} 

Khởi động máy chủ, khởi động máy khách. Bạn sẽ thấy rằng nó in "connected: true" hai lần, mặc dù socket được đóng lần thứ hai.

Cách duy nhất để thực sự tìm hiểu là bằng cách đọc (bạn sẽ nhận được -1 là giá trị trả về) hoặc viết (IOException (đường ống bị hỏng) sẽ được ném) trên InputStreams được kết hợp.

+1

Trong ví dụ của bạn, máy chủ không đóng kết nối TCP một cách duyên dáng (RST được gửi và đó là nó). Nếu bạn gọi close() trên socket của máy khách, kết nối sẽ được đóng một cách duyên dáng. Bạn có thể thấy điều này bằng kết quả khác nhau của hoạt động đọc: SocketException được ném so với đọc trả về -1. – Alexander

+0

BTW, cảm ơn vì đã nhắc tôi về "bí ẩn" này trong cách làm việc của ổ cắm Java. Tôi đã hỏi một câu hỏi tiếp theo như sau: http://stackoverflow.com/questions/155243/why-is-it-impossible-without-attempting-io-to-detect-that-tcp-socket-was -gracef – Alexander

+4

Cách duy nhất để tìm hiểu là viết. Đọc từ một ổ cắm đột ngột đóng có thể không phải luôn luôn trở lại -1. http://stackoverflow.com/a/6404085/372643 – Bruno

11

Bạn cũng có thể kiểm tra lỗi luồng đầu ra ổ cắm trong khi ghi vào ổ cắm máy khách.

out.println(output); 
if(out.checkError()) 
{ 
    throw new Exception("Error transmitting data."); 
} 
+1

Bạn * có thể *, nhưng bạn sẽ không nhất thiết phải lấy nó ngay lập tức. – EJP

25

Vì câu trả lời sai lệch nên tôi quyết định kiểm tra điều này và đăng kết quả - bao gồm ví dụ kiểm tra.

Máy chủ ở đây chỉ ghi dữ liệu cho khách hàng và không mong đợi bất kỳ đầu vào nào.

Máy chủ:

ServerSocket serverSocket = new ServerSocket(4444); 
Socket clientSocket = serverSocket.accept(); 
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
while (true) { 
    out.println("output"); 
    if (out.checkError()) System.out.println("ERROR writing data to socket !!!"); 
    System.out.println(clientSocket.isConnected()); 
    System.out.println(clientSocket.getInputStream().read()); 
     // thread sleep ... 
    // break condition , close sockets and the like ... 
} 
  • clientSocket.isConnected() trả về luôn luôn đúng một lần sẽ kết nối khách hàng (và ngay cả sau khi ngắt kết nối) lạ !!
  • getInputStream() read()
    • làm cho sự chờ đợi chủ đề cho đầu vào miễn là khách hàng được kết nối và do đó làm cho chương trình của bạn không làm bất cứ điều gì -. Trừ khi bạn nhận được một số đầu vào
    • lợi nhuận -1 nếu client ngắt kết nối
  • out.checkError() là đúng ngay sau khi khách hàng bị ngắt kết nối vì vậy tôi khuyên
+18

checkError() là đúng ngay sau khi phát hiện lỗi khi viết và không sớm hơn. Nó chắc chắn không trở thành sự thật ngay khi khách hàng ngắt kết nối. -1 – EJP

-7

phương pháp này Socke t.Có sẵn ngay lập tức sẽ ném một SocketException nếu hệ thống từ xa đã bị ngắt kết nối/đóng kết nối.

+5

Không, nó sẽ không. Sai. Sai rồi. Thông tin sai lệch. – EJP

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