我在java中创建了一个到服务器的套接字,并且在套接字连接之后它创建了一个可以访问套接字输入和输出流的新线程,然后此线程在它们到来时阻止并处理输入行in。在java中处理套接字
据我所知,当输入流结束时,BufferedReader上的readln
方法将返回null。这并不一定意味着套接字是封闭的,但它呢?这是什么意思?所以我想要在套接字上运行close
方法来很好地关闭它。
我也明白,readln
方法可以抛出一个IOException,并且在套接字上调用close
方法(如果它当前被阻塞)后抛出。什么时候可以抛出?插入后仍然可以打开它,或者它会一直关闭并准备好进行垃圾回收等。
这是我现在的代码,我真的不知道如何正确处理断开连接。目前我认为如果在套接字正在等待线路时调用disconnect
方法,则可能最终陷入死锁,因为disconnect
将在套接字上调用close
。然后这将把IOException
放在readLine
上,然后这将导致该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 tutorial on sockets,但在我看来,它并没有真正涵盖这些细节。
谢谢!