Заглянуть в сокет InputStream

1

Я хотел бы протестировать соединение между клиентом и сервером в 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;
}
  • 0
    Что вам нужно, это Java NIO. Вы должны это проверить.
Показать ещё 4 комментария
Теги:
sockets

1 ответ

1
Лучший ответ

Тестирование является избыточным. Операции чтения или записи возвращают -1, если другой конец закрывается или отключается до или во время операции. Нет смысла "сначала проверять" соединение, потому что он может впоследствии не работать во время операции ввода-вывода.

См. Также другой ответ, упомянутый в комментариях.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню