[英]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.