java System.currenttimemillis() 在两台计算机之间有一个偏移量
java System.currenttimemillis() has an offset between two computers
我正在编写一个 ping 应用程序,用于测量两台计算机(A 和 B)之间的数据包 recv/send 时间。它测量 A->B->A 时间、A->B 时间和 B->A 时间。现在,我 运行 在计算 B->A 的平均时间时遇到了一些问题,它显示负值。计算机 B 在接收数据包时比计算机 A 有 "faster"/ 更长的时间。我正在使用我的自定义 class:
获取时间值
public class TimingClass {
public static long getTime() {
return System.currentTimeMillis();
}
}
客户端应用程序的输出如下所示:
Time of start: 1483531410095 // Time when the packet was sent from the client
Time on B: 1483531410538 // Time taken on the server and appended to the message
Packet arrival time: 1483531410104 // Time taken when the packet arrived back on the client
13:03:21: Total=272 Rate=30/s Lost=0 AvgRTT=35ms MaxRTT=63 A->B=449 B->A=-414
现在您可以看到,当消息从服务器返回时,客户端显示的时间值小于服务器所用的时间。
这是 client/server 代码,只有 recv/send 消息的部分:
// This is the sender thread on the client sending 30msgs/s
msgHandler.writeMessage(createMessage());
private String createMessage() {
long time = TimingClass.getTime();
String timeStr = Long.toString(time);
String message = "payload";
messageId++;
return messageId + "%" + timeStr + "-" + message;
}
// This is the server part running on the main thread
while ((msg = msgHandler.readMessage()) != null) {
catcherTime = TimingClass.getTime();
System.out.println("Message arrived: " + msg);
msgHandler.writeMessage(appendTime(msg, catcherTime));
}
// This is the receiving thread on the client side
while ((line = messageIO.readMessage()) != null) {
currentTime = TimingClass.getTime();
diff = currentTime - initTime;
messageAcc++;
numberOfMsgs++;
bufferElement.addListElement(currentTime, line);
if (diff > 1000) {
initTime = TimingClass.getTime();
bufferElement.setMsgAcc(messageAcc);
bufferElement.setMsgNumber(numberOfMsgs);
queue.put((bufferElement));
numberOfMsgs = 0;
bufferElement = new BufferQueueElement();
}
}
从代码中可以看出,打印出的值与上述时间变量的对应关系如下:
time -> Time of start
catcherTime -> Time on B
currentTime -> Packet arrival time
客户端每1秒处理一次消息。
那么,有没有人遇到过此类问题或知道如何变通或解决它?
P.S。
我试过使用 System.nanoTime()
但 A->B 平均时间开始显示负值。此外,一台机器是 运行 Windows 10(客户端),另一台是 Windows 8.1(服务器),它们通过家庭网络连接。我正在开发的最低 Java 版本是 5,两台机器都有 java 8。而且两台机器都通过 time.windows.com 同步,我在 运行 之前手动完成应用程序以确保它们已同步。
这是计算机科学中的一个已知问题,请参阅 Lamport timestamps。来自维基 link:
In a distributed system, it is not possible in practice to synchronize
time across entities (typically thought of as processes) within the
system; hence, the entities can use the concept of a logical clock
based on the events through which they communicate.
想象一下有人在 phone 上,假设你们正在互相询问不需要思考的简单问题。每当您向另一端的人询问某事时,答复都会延迟几秒钟。现在您有两种情况:要么您的问题收到延迟,要么答案延迟送达。无法判断哪种情况是真实的。事实上,它通常都在不同的部分。
鉴于您只有两个 senders/receivers,无法判断延迟的来源。您需要第三个实例作为中央控制站。
您对两个节点唯一能做的就是测量包裹双向传送所需的时间。
我正在编写一个 ping 应用程序,用于测量两台计算机(A 和 B)之间的数据包 recv/send 时间。它测量 A->B->A 时间、A->B 时间和 B->A 时间。现在,我 运行 在计算 B->A 的平均时间时遇到了一些问题,它显示负值。计算机 B 在接收数据包时比计算机 A 有 "faster"/ 更长的时间。我正在使用我的自定义 class:
获取时间值public class TimingClass {
public static long getTime() {
return System.currentTimeMillis();
}
}
客户端应用程序的输出如下所示:
Time of start: 1483531410095 // Time when the packet was sent from the client
Time on B: 1483531410538 // Time taken on the server and appended to the message
Packet arrival time: 1483531410104 // Time taken when the packet arrived back on the client
13:03:21: Total=272 Rate=30/s Lost=0 AvgRTT=35ms MaxRTT=63 A->B=449 B->A=-414
现在您可以看到,当消息从服务器返回时,客户端显示的时间值小于服务器所用的时间。
这是 client/server 代码,只有 recv/send 消息的部分:
// This is the sender thread on the client sending 30msgs/s
msgHandler.writeMessage(createMessage());
private String createMessage() {
long time = TimingClass.getTime();
String timeStr = Long.toString(time);
String message = "payload";
messageId++;
return messageId + "%" + timeStr + "-" + message;
}
// This is the server part running on the main thread
while ((msg = msgHandler.readMessage()) != null) {
catcherTime = TimingClass.getTime();
System.out.println("Message arrived: " + msg);
msgHandler.writeMessage(appendTime(msg, catcherTime));
}
// This is the receiving thread on the client side
while ((line = messageIO.readMessage()) != null) {
currentTime = TimingClass.getTime();
diff = currentTime - initTime;
messageAcc++;
numberOfMsgs++;
bufferElement.addListElement(currentTime, line);
if (diff > 1000) {
initTime = TimingClass.getTime();
bufferElement.setMsgAcc(messageAcc);
bufferElement.setMsgNumber(numberOfMsgs);
queue.put((bufferElement));
numberOfMsgs = 0;
bufferElement = new BufferQueueElement();
}
}
从代码中可以看出,打印出的值与上述时间变量的对应关系如下:
time -> Time of start
catcherTime -> Time on B
currentTime -> Packet arrival time
客户端每1秒处理一次消息。 那么,有没有人遇到过此类问题或知道如何变通或解决它?
P.S。
我试过使用 System.nanoTime()
但 A->B 平均时间开始显示负值。此外,一台机器是 运行 Windows 10(客户端),另一台是 Windows 8.1(服务器),它们通过家庭网络连接。我正在开发的最低 Java 版本是 5,两台机器都有 java 8。而且两台机器都通过 time.windows.com 同步,我在 运行 之前手动完成应用程序以确保它们已同步。
这是计算机科学中的一个已知问题,请参阅 Lamport timestamps。来自维基 link:
In a distributed system, it is not possible in practice to synchronize time across entities (typically thought of as processes) within the system; hence, the entities can use the concept of a logical clock based on the events through which they communicate.
想象一下有人在 phone 上,假设你们正在互相询问不需要思考的简单问题。每当您向另一端的人询问某事时,答复都会延迟几秒钟。现在您有两种情况:要么您的问题收到延迟,要么答案延迟送达。无法判断哪种情况是真实的。事实上,它通常都在不同的部分。
鉴于您只有两个 senders/receivers,无法判断延迟的来源。您需要第三个实例作为中央控制站。
您对两个节点唯一能做的就是测量包裹双向传送所需的时间。