简体   繁体   English

窥探套接字InputStream

[英]Peek on a socket InputStream

I would like to test the connection between a client and a server in a ScheduledExecutorService every x ms while processing received data from the distant host. 我想在处理来自远程主机的接收到的数据时每隔x ms测试一个ScheduledExecutorService中的客户端与服务器之间的连接。

So I did something like this: 所以我做了这样的事情:

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's inputstream to know if something's wrong
    }

    private void myProcessing() {
        while (true) {
            ...

            //read what's inside stream
            //process it in a thread
        }
    }
} 

So, if I .read() on the Socket's inputstream it'll screw myProcessing(). 因此,如果我在Socket的输入流上读取.read(),它将使myProcessing()陷入困境。 I thought about wraping the inputstream in a BufferedReader and mark the buffer position before I read and then reset the position, but as the testing and the processing are in two differents thread it won't work anyway. 我考虑过将输入流包装在BufferedReader中,并在读取并重设位置之前标记缓冲区位置,但是由于测试和处理处于两个不同的线程中,因此无论如何都无法正常工作。

How can I do that? 我怎样才能做到这一点? Knowing that I did it in c# without much problem: 知道我在c#中做到了,没什么大问题:

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;
    }
}

Thank you 谢谢

Edit: I would like to make something like that: 编辑:我想做这样的事情:

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;
}

The testing is redundant. 测试是多余的。 The read or write operations will return -1 if the other end closes or disconnects before or during the operation. 如果在操作之前或操作过程中另一端关闭或断开连接,则读或写操作将返回-1。 There is no point in "testing" the connection first because it may subsequently fail during your IO operation. 首先没有必要“测试”连接,因为在IO操作期间,连接可能随后失败。

See also the other answer mentioned in the comments. 另请参见注释中提到的其他答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM