最近在做基于socket 长连接的东西,需要用到重新连接socket。从网上学习了,在这边转发。
package com.socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 定时重连socket
*
* 扩展应用:socket虽然表面上连着,但实际上可能已经断了,那么在某些条件的触发下(比如60分钟没获得socket数据),重新连接socket服务
*
* @author jch
*
*/
public class ReconnectSocket extends Thread {
private Socket socketClient;
private String host = "localhost";
private String port = "1111";
private BufferedReader reader;
private boolean flag_forEver = false;// 保证线程存活的标志
private boolean flag_connectedSocket = true;// socket连接是否成功的标识
private boolean flag_forReConnectSocket = false;// socket重新连接时用到的暂停标识
private ListenForSocket lfs;// socket重连监视线程
public ReconnectSocket() {
try {
connectSocket();
lfs = new ListenForSocket();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接socket
*
* @throws Exception
*/
private synchronized void connectSocket() throws Exception {
try {// 关闭socket
if (socketClient != null) {
try {
socketClient.shutdownInput();
socketClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// socket重新连接
socketClient = new Socket(host, Integer.parseInt(port));
socketClient.setKeepAlive(true);
socketClient.setSoLinger(true, 0);
socketClient.setReceiveBufferSize(81920);
reader = new BufferedReader(new InputStreamReader(socketClient
.getInputStream()));
flag_connectedSocket = true;
} catch (Exception e) {
new Exception("连接socket出现问题").printStackTrace();
flag_connectedSocket = false;
}
}
/**
* 重新连接socket
*
*/
public void reconnectSocket() {
try {
flag_forReConnectSocket = false;
connectSocket();
flag_forReConnectSocket = true;
} catch (Exception e) {
}
}
public void start() {
lfs.start();
flag_forEver = true;
flag_forReConnectSocket = true;
super.start();
}
public void cancel() {
lfs.cancel();
flag_forEver = false;
flag_forReConnectSocket = false;
}
public void run() {
while (flag_forEver) {// 保证线程存活的标志
try {
if (!flag_connectedSocket) {// 判断socket是否已经连上了,保证连上socket
connectSocket();
sleep(1000);
continue;
}
String str = "";
while (flag_forReConnectSocket) {// socket定时重接时用到的暂停标识
try {
if ((str = reader.readLine()) != null) {
System.out.println(str);
}
} catch (java.net.SocketException socket_e) {
// 不作处理--重连socket时可能抛出的错误
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 定时重连socket的线程
*
* @author jch
*
*/
class ListenForSocket extends Thread {
private boolean flag = false;
public void start() {
flag = true;
super.start();
}
public void cancel() {
flag = false;
}
public void run() {
while (flag) {
try {
// 当socket已经连上了才作重连,本身就没连上的情况,有另外的机制在重连
// 根据不同的业务需要增加重连的其他限制条件,如果不加其他限制的条件的话,socket将定时重连
if (flag_connectedSocket && true) {
reconnectSocket();
}
sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new ReconnectSocket().start();
}
}