簡體   English   中英

窺探套接字InputStream

[英]Peek on a socket InputStream

我想在處理來自遠程主機的接收到的數據時每隔x ms測試一個ScheduledExecutorService中的客戶端與服務器之間的連接。

所以我做了這樣的事情:

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

因此,如果我在Socket的輸入流上讀取.read(),它將使myProcessing()陷入困境。 我考慮過將輸入流包裝在BufferedReader中,並在讀取並重設位置之前標記緩沖區位置,但是由於測試和處理處於兩個不同的線程中,因此無論如何都無法正常工作。

我怎樣才能做到這一點? 知道我在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;
    }
}

謝謝

編輯:我想做這樣的事情:

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。 首先沒有必要“測試”連接,因為在IO操作期間,連接可能隨后失敗。

另請參見注釋中提到的其他答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM