2013-02-21 18 views
6

Vì vậy, tôi đã viết một chủ đề ở phía khách hàng của mình, cố gắng để readObject() từ một dòng socket.Java - readObject() và setSoTimeout()

Chuỗi này chạy khi khách hàng được kết nối lâu.

Kết nối với máy chủ có thể được đóng trên GUI của máy khách. Nếu khách hàng quyết định ngắt kết nối (điều này sẽ không thoát khỏi chương trình khách hàng) bằng cách nhấp vào tùy chọn menu "ngắt kết nối", ổ cắm sẽ bị đóng và isConnected được đặt thành false.

Vì khách hàng đọc chủ đề cố gắng readObject() từ luồng, trong khi kết nối có thể được đóng qua GUI, tôi đặt thời gian chờ là 250ms (setSoTimeout(250)).

@Override 
public void run() 
{ 
    this.connection = this.connectionHandler.getSocket(); 
    while(connectionHandler.isConnected()) 
    { 
    this.readCircle(); 
    } 
    this.connectionHandler.setReadTaskRunning(false); 
} 

private void readCircle() 
{ 
    try 
    { 
    this.connection.setSoTimeout(250); 
    this.connectionHandler.readData(); //this uses readObject(). 
    } 
catch(SocketTimeoutException timeout){} 
catch(...){} 

}

Tôi biết rằng readObject() sẽ chặn, và để kiểm tra xem khách hàng vẫn còn kết nối, tôi wraped nó trong một while, trong đó kiểm tra (mỗi timeout) nếu client socket vẫn được kết nối.

Câu hỏi của tôi bây giờ là:

Trong trường hợp, nếu readObject() bắt đầu để có được một đối tượng thông qua máy chủ, cố gắng đọc nó, nhưng khi xử lý một timeout xảy ra, sẽ dữ liệu trên dòng được "hư hỏng" theo một cách nào đó, bởi vì nó bị hủy bỏ. Hoặc tôi chỉ nên để khối readObject() và bắt ngoại lệ nếu chuỗi GUI muốn đóng socket.

Tôi không có nhiều kinh nghiệm về ổ cắm và có lẽ cách tiếp cận của tôi là sai.

+1

isConnected() không trả về false nếu peer đã ngắt kết nối. Bạn phải nắm bắt và xử lý EOFException. – EJP

+0

Vâng, bạn có quyền. Bắt '(...) {}' tôi phải nắm bắt một loạt các ngoại lệ. Việc bắt giữ 'EOFException' sẽ gọi một' forceDisconnect() 'để đóng các tài nguyên ở phía máy khách và cũng điều chỉnh Các phần tử GUI cho người dùng. – Hexa

Trả lời

2

Thời gian chờ đọc của ổ cắm sẽ gây ra SocketTimeoutException để được ném bởi readObject(). Bạn không thể sử dụng lại ObjectInputStream và luồng này có thể bị hỏng vì vị trí hiện tại của nó sẽ không được xác định phần lớn.

Điều này có thể chỉ có thể được sửa bằng cách đóng và mở lại kết nối.