3
 class LogWriter implements Runnable {

Socket client;

private static ThreadLocal<Date> date = new ThreadLocal<Date>() {
@Override
protected Date initialValue() {
    return new Date();
};
};

private static ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
    return new SimpleDateFormat("yyyy_MM_dd");
};
};

public LogWriter(Socket client) {
this.client = client;
}

public void run() {
try {
    write(this.client.getInputStream(), new File(
        CentralizedLogging.logsDir + File.separator
            + client.getInetAddress().getHostName() + "_"
            + getFormattedDate() + ".log"));
    this.client.close();
} catch (Exception e) {
    try {
    e.printStackTrace();
    write(new ByteArrayInputStream(e.getMessage().getBytes()),
        new File(CentralizedLogging.logsDir + File.separator
            + "centralLoggingError.log"));
    } catch (IOException io) {

    }
}
}

  public synchronized void write(InputStream in, File file)
    throws IOException {
RandomAccessFile writer = new RandomAccessFile(file, "rw");
writer.seek(file.length()); // append the file content into existing if it not exist creating a new one.
writer.write(read(in));
writer.close();
}

public static byte[] read(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int read = -1;
byte[] buffer = new byte[1024];
read = in.read(buffer);
do {
    out.write(buffer, 0, read);
} while((read = in.read(buffer)) > -1);
return out.toByteArray();
}

主要方法

   public static void main(String[] args) throws InterruptedException,
    IOException {
// CentralizedLogging centralLogServer = new CentralizedLogging(args[0],Integer.parseInt(args[1]));
// new Thread(centralLogServer).start();
long start = System.currentTimeMillis() + 1000 * 20 * 60;
while(start >= System.currentTimeMillis()) {
    Socket client = new Socket("bharathi-1397", 10000);
    OutputStream os = client.getOutputStream();
    DataOutputStream outToServer = new DataOutputStream(os);
    outToServer
        .write("Centralized Logging is working......".getBytes());
    client.close();
}
}

我正确关闭了连接。但是 time_wait 连接正在增加。我从我的终端拍了一张快照,我发布了其中的一部分。我错过了什么吗?

 tcp6       0      0 127.0.0.1:46146         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:57645         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:47961         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:56716         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:49469         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:54078         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:51626         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:50143         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:59214         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:54192         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:53436         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:54547         127.0.0.1:10000         TIME_WAIT   -               
 tcp6       0      0 127.0.0.1:55032         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:51273         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:48381         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:47532         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:56811         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:55293         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:56664         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:49242         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:51225         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59265         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59378         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:47997         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:47955         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59453         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:48092         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:52462         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59579         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:54921         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:55675         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:51140         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:57321         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:51656         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:54740         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:53600         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59862         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:54766         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:59062         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:55702         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:50942         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:53732         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:52757         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:56430         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:49179         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:48689         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:53313         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:51161         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:57033         127.0.0.1:10000         TIME_WAIT   -               
tcp6       0      0 127.0.0.1:58607         127.0.0.1:10000         TIME_WAIT   - 

它会对我的服务器造成任何问题吗?这是什么原因?.

4

1 回答 1

3

我正在正确关闭连接,但 time_wait 连接正在增加。我错过了什么吗?

内核使用TIME_WAIT它来确保您的 TCP 流不会重复使用可能仍有数据包从远程端发送到它的端口。根据TIME_WAIT网络设置,时间通常设置为数据包最长使用期限的两倍。

如果您正在获得许多新连接,那么您会看到端口数量在TIME_WAIT 增加,但在某些时候它应该会稳定下来,除非连接速率也在增加。要做的一件事是对所有TIME_WAIT行进行 grep,对它们进行排序并查看端口号是否正在更改。如果正在添加新端口而旧端口脱落,那么一切都很好。

要尝试的一件事是确保您的客户正在发起close()呼叫。那将留TIME_WAIT在客户端而不是服务器上。请参阅这个关于服务器的优秀页面TCP及其含义TIME_WAIT

由于您的服务器似乎正在向客户端发送文件(如果我正确阅读了您的代码),您应该考虑将协议更改为如下所示。这将导致客户端首先关闭,因此大多数TIME_WAITs 将位于每个客户端上。

  1. 服务器先发送文件的长度
  2. 服务器发送文件
  3. 客户端读取长度
  4. 客户端读取文件字节
  5. 客户发送“得到它”
  6. 客户关闭
  7. 服务器读取客户端的“得到它”消息
  8. 服务器关闭

您是否看到关于让客户制作第close()一个@kannan 的内容?如果服务器正在发送文件,那么我会让它发送文件,然后等待客户端发送“得到它”消息。然后客户端可以读取文件,读取 EOF 标记,发送“得到它”,然后立即关闭。

另外,顺便说一句,您应该try ... finally在代码中使用模式。就像是:

public void run() {
    try {
        write(this.client.getInputStream(), new File(
            CentralizedLogging.logsDir + File.separator
            + client.getInetAddress().getHostName() + "_"
            + getFormattedDate() + ".log"));
    } catch (Exception e) {
        try {
            e.printStackTrace();
            write(new ByteArrayInputStream(e.getMessage().getBytes()),
                new File(CentralizedLogging.logsDir + File.separator
                + "centralLoggingError.log"));
        } catch (IOException io) {
        }
    } finally {
        // always close in the finally
        this.client.close();
    }
}
于 2012-05-23T19:20:11.007 回答