我正在使用持久 TCP 套接字将数据从我的系统发送到第三方系统。它工作正常,但有时由于第三方系统中的一些错误,连接速度减慢,并减慢了我的应用程序的速度。
如何捕捉这个状态?我应该设置连接超时吗?因为当发生这种情况时,我需要关闭现有套接字并在一段时间后重新建立一个新套接字。
代码如下:
public static void initializeCongServer() throws Exception {
try{
Calendar currentTime = Calendar.getInstance();
if(congestionDownStartTime!=null){
long timeInSecs = (currentTime.getTimeInMillis() - congestionDownStartTime.getTimeInMillis())/1000;
if(timeInSecs < config.getCongestionReconnectTimeInSecs()){
logWrapper1.log(Level.DEBUG, "Packet not sent to Congestion as it was down when last checked. Connection to congestion will be retried again in: "+ (config.getCongestionReconnectTimeInSecs() - timeInSecs)+" seconds");
return;
}
}
if(congConnector!=null){
congConnector.close();
if(congConnector.sock!=null){
congConnector.sock.close();
}
congConnector = null;
}
logWrapper1.log(Level.DEBUG, "Reconnecting with congestion server.");
congConnector = new Connector(config.getCongServerIP(), config.getCongServerPort(), 1, 2);
congConnector.connect();
congestionDownStartTime = null;
} catch(Exception e){
congestionDownStartTime = Calendar.getInstance();
logWrapper1.log(Level.DEBUG, e.getMessage());
e.printStackTrace();
}
}
public static void sendDataToCongServer(String data){
try {
System.out.println("CONGESTION: "+data);
synchronized(Main.class){
if(congConnector!=null && congConnector.connected==true){
congConnector.send(data, false, false, 1);
}else{
initializeCongServer();
}
}
} catch (Exception ex) {
congestionDownStartTime = Calendar.getInstance();
logWrapper1.log(Level.DEBUG, "CONGESTION DOWN: "+data);
logWrapper1.log(Level.DEBUG, ex.getMessage());
}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class Connector {
String host = null;
int port = 0;
int index = 0;
long reconnectTime = 0;
Socket sock = null;
boolean connected = false;
InputStream inputStream = null;
OutputStream outputStream = null;
BufferedReader bufferedReader = null;
DataOutputStream dataOutputStream = null;
public Connector(String host, int port, int index, long reconnectTime) throws Exception {
this.host = host;
this.port = port;
this.index = index;
this.reconnectTime = reconnectTime;
}
public synchronized Socket reconnect() throws Exception {
sock = new Socket(host, port);
inputStream = sock.getInputStream();
outputStream = sock.getOutputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
dataOutputStream = new DataOutputStream(outputStream);
connected = true;
return sock;
}
public void close() {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
//Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException ex) {
//Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
private synchronized void notifyWait() {
connected = false;
}
public synchronized void connect() throws Exception {
reconnect();
}
public void send(String str, boolean appendLine, boolean bindResult, int MedReadTimeOut) throws Exception {
String result = null;
if (connected == true) {
try {
byte[] b = null;
if (appendLine == true) {
b = (str + "\r\n").getBytes();
} else {
b = str.getBytes();
}
dataOutputStream.write(b, 0, b.length);
dataOutputStream.flush();
} catch (IOException ex) {
notifyWait();
connected = false;
throw new Exception(ex);
}
if (bindResult == true) {
try {
sock.setSoTimeout(MedReadTimeOut);
result = bufferedReader.readLine();
}
catch (SocketTimeoutException sockEx) {
String debugInfo = "TIMEOUT= "+MedReadTimeOut+".MEDIATION PORT CLOSED " + sock.getPort();
System.out.println(debugInfo);
}
catch (IOException ex) {
//Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
notifyWait();
throw new Exception(ex);
}
}
} else {
throw new Exception("Congestion Socket Closed.");
}
}
}
最佳答案
连接超时没有帮助,因为它定义了启动连接的最大允许时间。如果有的话,您可能想尝试 setSoTimeout()相反。
但一般来说,使用套接字超时捕获这种情况并不是最佳选择,因为只要某些信息偶尔到达,即使一次只有一个字节,套接字就不会超时。
为了获得更强大的解决方案,我建议在应用程序级别解决问题,而不是套接字级别。也许使用 moving average检查给定时间范围内(例如最后 5 分钟)通过有问题的套接字接收/发送的数据量,如果平均值低于预定义阈值,则重新连接。
关于Java:确定 TCP 套接字何时变慢并重新建立连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25176555/