Java:确定 TCP 套接字何时变慢并重新建立连接

标签 java sockets

我正在使用持久 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/

相关文章:

java - CellFactory 与 CellValueFactory

java - 由于 ClassNotFoundException 而无法启动 Activity

c - 如何检查端口是否可用

c# - socket 应该保持打开还是拆除

python - Django Channels No module named 'asgiref.sync' 错误

java - gwt 套接字连接

java - 将 long 转换为 int 是否比将 long 转换为 Long 的自动装箱便宜?

java - 为什么按钮显示错误的颜色?

java - 自定义 Emma 报告生成

VBA 与 WinSock2 : send() sends wrong data