客户端重新连接java套接字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9794559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
client reconnect java socket
提问by user1217609
ok i need to write a client that can be able to detect the connection between client and server...once server is close and bring back up my client need to be able to connect it back to the server..but i am really not sure how to do it...any help if possible?
好的,我需要编写一个能够检测客户端和服务器之间连接的客户端......一旦服务器关闭并恢复我的客户端需要能够将其连接回服务器......但我真的不是确定怎么做...如果可能的话有什么帮助吗?
public TEST(String serverIP, int serverPort){
Log("Connection to the Server....");
try{
socket = new Socket(serverIP, serverPort);
Log("Connected to the server : "+socket);
start();
} catch(UnknownHostException uhe){
System.out.println("Unknown Host: "+ uhe.getMessage());
} catch (IOException ioe){
System.out.println("IO Exception: "+ioe.getMessage());
}
String readline = "";
streamOutput.println("TRY test");
while(true){
try{
readline = streamInput.readLine();
System.out.println(readline);
} catch (IOException ioe){
System.out.println("Error in sending: "+ioe.getMessage());
return;
}
}
}
above is my client code that use to connect to a server once it is compiled...
上面是我的客户端代码,用于在编译后连接到服务器...
采纳答案by JohnnyK
The only way to know a connection is closed is to try sending data over the wire. Connections don't automatically test open/closed status. If you want to check for an closed connection and reconnect, you'll have to send a heartbeat signal from one to the other. Usually, it's just a special byte or tiny message that tells the other side "I'm still here"
知道连接已关闭的唯一方法是尝试通过线路发送数据。连接不会自动测试打开/关闭状态。如果要检查关闭的连接并重新连接,则必须从一个连接到另一个发送心跳信号。通常,它只是一个特殊的字节或微小的消息,告诉对方“我还在这里”
But then, depending on your application, you may not need that. Do both sides of your application start messages? Or is it an RMI-style app? Where the server just listens for requests?
但是,根据您的应用程序,您可能不需要它。您的应用程序的双方都启动消息吗?或者它是一个 RMI 风格的应用程序?服务器在哪里只侦听请求?
Maybe something like this?
也许是这样的?
class Client {
private Socket socket;
private boolean tryToReconnect = true;
private final Thread heartbeatThread;
private long heartbeatDelayMillis = 5000;
public Client(final String server, final int port) {
connect(server, port);
heartbeatThread = new Thread() {
public void run() {
while (tryToReconnect) {
//send a test signal
try {
socket.getOutputStream().write(666);
sleep(heartbeatDelayMillis);
} catch (InterruptedException e) {
// You may or may not want to stop the thread here
// tryToReconnect = false;
} catch (IOException e) {
logger.warn("Server is offline");
connect(server, port);
}
}
};
};
heartbeatThread.start();
}
private void connect(String server, int port){
try {
socket = new Socket(server, port);
} catch (UnknownHostException e) {
logger.error(e, e);
} catch (IOException e) {
logger.error(e, e);
}
}
public void shutdown() {
tryToReconnect = false;
}
}
回答by DerMike
When your client catches a SocketException
it should enter its tryToReconnectstate. Now it probes the server at some interval (e. g. 1 sec maybe more, depending on the server). Make sure you implement some logic to stop that when it is not needed anymore.
当您的客户端捕获 a 时,SocketException
它应该进入它的tryToReconnect状态。现在它以某个时间间隔(例如,1 秒可能更长,取决于服务器)探测服务器。确保您实现了一些逻辑以在不再需要时停止它。
回答by Darrell Teague
This is a pretty common problem (needing to know when the pipe is broken) and one of the answers was correct in the approach stating that the Clientwill need to 'check' the socket (periodically) to see if it is closed. The Serverwill not notify the Clientthe socket is closed and indeed, cannot because it is, well, closed. Firewalls, proxies and the like in between the Clientand Servermay have killed or otherwise blocked socket communication in one or both directions at any point after the connection is made.
这是一个非常常见的问题(需要知道管道何时损坏)并且该方法中的一个答案是正确的,即客户端将需要(定期)“检查”套接字以查看它是否已关闭。该服务器将不通知客户关闭套接字而事实上,不能因为它是,好吧,关门。客户端和服务器之间的防火墙、代理等可能在建立连接后的任何时候终止或以其他方式阻止一个或两个方向的套接字通信。
First, if you have done a lot of socket programming (in "C" or Java, etc) ... you will have seen the "attempting to write on broken pipe" type error/exception. This is an I/O class of error when the Clienttries to write (send) data on a closed socket (which was just then detected to have been closed).
首先,如果您已经完成了很多套接字编程(在“C”或 Java 等中)……您将看到“试图在损坏的管道上写入”类型的错误/异常。当客户端尝试在关闭的套接字(刚刚检测到已关闭)上写入(发送)数据时,这是一个 I/O 类错误。
So the answer lies in managing the socket above the Socket creation layer.
所以答案在于管理Socket创建层之上的socket。
That is, a thread on the Clientwill need to be monitoring the socket by sending data (periodically to the server as a kind of 'ping' to check for a broken-pipe condition) and then destroy (clean-up) and re-create the socket (rinse and repeat) if an I/O error occurs.
也就是说,客户端上的线程需要通过发送数据(定期发送到服务器作为一种“ping”来检查管道损坏情况)来监视套接字,然后销毁(清理)并重新如果发生 I/O 错误,则创建套接字(冲洗并重复)。
Note that a more complex bi-directional bit of logic would be better provided the Clientcould ensure an expected and consistent (and timely) response from the Server for a given 'ping'. This would concretely confirm the bi-directional traffic is flowing. Otherwise firewalls could be closing traffic in one direction whilst the Client believes it is still 'talking' to the Server(which may well be receiving data but not able to transmit back to the Client - possibly causing it to terminate the connection on inactivity timeout).
请注意,如果客户端可以确保服务器对给定的“ping”做出预期和一致(和及时)的响应,则更复杂的双向逻辑会更好。这将具体确认双向流量正在流动。否则防火墙可能会关闭一个方向的流量,而客户端认为它仍在与服务器“交谈” (服务器很可能正在接收数据但无法传输回客户端 - 可能导致它在不活动超时时终止连接) .