我正在用java创建一个到服务器的套接字,在连接套接字后它会创建一个新线程,该线程可以访问套接字输入和输出流,然后这个线程在输入行进入时阻塞并处理它们。
我知道readln
BufferedReader 上的方法将在输入流结束时返回 null 。这并不一定意味着套接字已关闭,不是吗?这是什么意思?所以我想close
在套接字上运行该方法以很好地关闭它。
我也知道该readln
方法可以抛出一个 IOException ,并且close
如果当前阻塞,则在套接字上调用该方法后抛出该异常。这还能扔到什么时候?抛出此套接字后套接字是否仍处于打开状态,或者它是否始终处于关闭状态并准备好进行垃圾收集等?
这是我目前拥有的代码,我真的不知道如何正确处理断开连接。目前我认为如果在disconnect
套接字等待一行时调用该方法,这可能会导致死锁,因为disconnect
将调用close
套接字。然后这将引发IOException
onreadLine
并且这将导致该 catch 块disconnect
再次调用。
public class SocketManager {
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
private String ip;
private int port;
private Object socketLock = new Object();
public SocketManager(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void connect() throws UnableToConnectException, AlreadyConnectedException {
synchronized(socketLock) {
if (socket == null || socket.isClosed()) {
throw (new AlreadyConnectedException());
}
try {
socket = new Socket(ip, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
throw (new UnableToConnectException());
}
new Thread(new SocketThread()).start();
}
}
public void disconnect() throws NotConnectedException {
synchronized(socketLock) {
if (isConnected()) {
throw (new NotConnectedException());
}
try {
socket.close();
} catch (IOException e) {}
}
}
public boolean isConnected() {
synchronized(socketLock) {
return (socket != null && !socket.isClosed());
}
}
private class SocketThread implements Runnable {
@Override
public void run() {
String inputLine = null;
try {
while((inputLine = in.readLine()) != null) {
// do stuff
}
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e) {}
}
} catch (IOException e) {
// try and disconnect (if not already disconnected) and end thread
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e1) {}
}
}
}
}
}
我基本上想知道实现以下目标的最佳方法:
- 编写连接到套接字并启动一个单独的线程来监听输入的连接方法。
- 编写一个断开与套接字断开连接并终止正在侦听输入的线程的断开方法。
- 处理与远程套接字的连接断开的情况。
我已经阅读了有关套接字的 java 教程,但在我看来,它并没有真正详细介绍这些内容。
谢谢!