Javaでサーバーへのソケットを作成しています。ソケットが接続された後、ソケットの入力ストリームと出力ストリームにアクセスできる新しいスレッドが作成され、このスレッドは入力行が入ってくるとブロックして処理します。
readln
入力ストリームが終了すると、BufferedReaderのメソッドが null を返すことを理解しています。これは必ずしもソケットが閉じていることを意味するわけではありませんか? これは何を意味するのでしょうか?close
したがって、ソケットでメソッドを実行して、ソケットをうまく閉じたいと思います。
readln
また、メソッドが IOException をスローする可能性があること、およびclose
メソッドが現在ブロックされている場合、ソケットでメソッドが呼び出された後にこれがスローされることも理解しています。他にいつこれを投げることができますか?これがスローされた後もソケットがまだ開いている可能性がありますか、それとも常に閉じており、ガベージ コレクションなどの準備ができている可能性があります。
これは私が現在持っているコードであり、切断を適切に処理する方法がよくわかりません。disconnect
ソケットがラインを待っている間にメソッドが呼び出されると、ソケットでdisconnect
呼び出すため、現時点ではデッドロックに陥る可能性があると思いclose
ます。IOException
これによりonがスローさ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チュートリアルを読みましたが、私の意見では、これらについてはあまり詳しく説明していません。
ありがとう!