Я хотел бы протестировать соединение между клиентом и сервером в ScheduledExecutorService каждые x ms при обработке полученных данных с удаленного хоста.
Поэтому я сделал что-то вроде этого:
public class MyClass {
private final ScheduledExecutorService _timer = Executors.newScheduledThreadPool(1);
private Socket _connection;
public void connectToDistantHost() {
try {
_connection = new Socket();
_connection.connect(_adresseServeur);
new Thread(new Runnable() {
@Override
public void run() {
try {
//let another object know the connection is ok
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
_timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
testConnection();
}
}, 0, 200, TimeUnit.MILLISECONDS);
}
private void testConnection() {
//would like to peek on the socket inputstream to know if something wrong
}
private void myProcessing() {
while (true) {
...
//read what inside stream
//process it in a thread
}
}
}
Итак, если я.read() на входном входе Socket, он закроет myProcessing(). Я подумал о том, чтобы сокрушить входной поток в BufferedReader и пометить позицию буфера перед тем, как я прочитал, а затем сбросить позицию, но поскольку тестирование и обработка в двух разных потоках не будут работать, все равно.
Как я могу это сделать? Зная, что я сделал это в С# без особых проблем:
class TraitementEnvoiClient {
...
private void testConnection(Object obj, ElapsedEventArgs args) {
_connectionIsOk = _connexionAuServeur.IsConnected();
if (!_connectionIsOk) {
tryToReconnect();
}
}
}
public static class ExtensionTcpClient {
//Credit to ElFenix: http://social.msdn.microsoft.com/Forums/en-US/c857cad5-2eb6-4b6c-b0b5-7f4ce320c5cd/c-how-to-determine-if-a-tcpclient-has-been-disconnected?forum=netfxnetcom
public static bool IsConnected(this TcpClient client) {
// Detect if client disconnected
try {
if (client.Client.Poll(0, SelectMode.SelectRead)) {
byte[] buff = new byte[1];
if (client.Client.Receive(buff, SocketFlags.Peek) == 0) {
// Client disconnected
return false;
}
}
} catch (SocketException se) {
return false;
}
return true;
}
}
спасибо
Изменение: Я хотел бы сделать что-то вроде этого:
private static boolean isConnected(Socket client) {
try {
InputStream is = client.getInputStream();
if(is.peek() == -1) return false;
OutputStream os = client.getOutputStream();
os.write(new byte[]{}); //if it fails a IOException will trigger
} catch(SocketException se) {
return false;
} catch(IOException ioe) {
return false;
}
return true;
}
Тестирование является избыточным. Операции чтения или записи возвращают -1, если другой конец закрывается или отключается до или во время операции. Нет смысла "сначала проверять" соединение, потому что он может впоследствии не работать во время операции ввода-вывода.
См. Также другой ответ, упомянутый в комментариях.