- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我看到一个问题(SLES11 上的 Java 6),其中一个 UDP 数据包被发送回客户端机器(并且客户端机器上的 tcpdump
显示它被接收),但是数据包没有' 被 Java 看到。
测试是这样的:
客户端生成一些随机数据,将其放入 UDP 数据包中,通过特定端口将其发送到服务器并等待其回显(SO_TIMEOUT
为 180000 毫秒) .当它收到它时,它会打印出它已经收到它以及它被发送了多长时间。
服务器端在该端口上监听 UDP 数据包。当它收到它时,它会延迟一点然后立即将其发送回去,不变。延迟从某个初始值(3000 毫秒)开始,然后每次收到数据包时加倍,直到达到最大值(90000 毫秒),之后延迟保持在最大值。
在延迟达到 48000 毫秒之前它工作正常。客户端上运行的 tcpdump
显示正在发送的数据包,并显示 48000 毫秒后到达的回复数据包。但是,Java 程序永远不会看到该回复数据包,并且在 180000 毫秒后声称接收超时。尽管客户端计算机仅在 48000 毫秒后收到数据包,如 tcpdump
所示。
会发生什么?
下面是程序和tcpdump
的输出,之后是客户端和服务器程序的源代码。
在客户端机器上,测试程序输出为:
rich-ova3:~/UDPTest2 # java -cp . Client
Properties:
-- listing properties --
ServerPort=20000
Timeout=180000
Server=rich-ova5.teak.eng
Loops=8
DatagramLength=333
UDP socket timeout is 180000 ms
Sending packet 1 of 8
Received packet 1 of 8
Round-trip time: 3001 ms
Sending packet 2 of 8
Received packet 2 of 8
Round-trip time: 6001 ms
Sending packet 3 of 8
Received packet 3 of 8
Round-trip time: 12001 ms
Sending packet 4 of 8
Received packet 4 of 8
Round-trip time: 24000 ms
Sending packet 5 of 8
Error receiving: Receive timed out
java.net.SocketTimeoutException: Receive timed out
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at Client.go(Client.java:80)
at Client.main(Client.java:39)
Round-trip time: 180096 ms
Sending packet 6 of 8
Error receiving: Receive timed out
java.net.SocketTimeoutException: Receive timed out
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at Client.go(Client.java:80)
at Client.main(Client.java:39)
Round-trip time: 180087 ms
Sending packet 7 of 8
Error receiving: Receive timed out
java.net.SocketTimeoutException: Receive timed out
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at Client.go(Client.java:80)
at Client.main(Client.java:39)
Round-trip time: 180093 ms
Sending packet 8 of 8
Error receiving: Receive timed out
java.net.SocketTimeoutException: Receive timed out
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at Client.go(Client.java:80)
at Client.main(Client.java:39)
Round-trip time: 180078 ms
Send successes: 8
Send errors: 0
Receive successes: 4
Receive errors: 4
客户端 机器上的tcpdump
输出(我的评论内嵌)是:
16:03:42.438252 IP 172.16.20.113.16362 > 172.16.20.115.20000: UDP, length 333
16:03:45.439322 IP 172.16.20.115.20000 > 172.16.20.113.16362: UDP, length 333
(a 3011 ms delay)
16:03:45.440315 IP 172.16.20.113.25559 > 172.16.20.115.20000: UDP, length 333
16:03:51.441394 IP 172.16.20.115.20000 > 172.16.20.113.25559: UDP, length 333
(a 6001 ms delay)
16:03:51.441938 IP 172.16.20.113.30457 > 172.16.20.115.20000: UDP, length 333
16:04:03.442564 IP 172.16.20.115.20000 > 172.16.20.113.30457: UDP, length 333
(a 12000 ms delay)
16:04:03.443095 IP 172.16.20.113.46143 > 172.16.20.115.20000: UDP, length 333
16:04:27.443572 IP 172.16.20.115.20000 > 172.16.20.113.46143: UDP, length 333
(a 24001ms delay)
16:04:27.444109 IP 172.16.20.113.31747 > 172.16.20.115.20000: UDP, length 333
16:05:15.444688 IP 172.16.20.115.20000 > 172.16.20.113.31747: UDP, length 333
(a 48001 ms delay)
16:07:27.540689 IP 172.16.20.113.38357 > 172.16.20.115.20000: UDP, length 333
16:08:57.541312 IP 172.16.20.115.20000 > 172.16.20.113.38357: UDP, length 333
(a 90000 ms delay)
16:10:27.627411 IP 172.16.20.113.33915 > 172.16.20.115.20000: UDP, length 333
16:11:57.631436 IP 172.16.20.115.20000 > 172.16.20.113.33915: UDP, length 333
(a 90004 ms delay)
16:13:27.720668 IP 172.16.20.113.36494 > 172.16.20.115.20000: UDP, length 333
16:14:57.722353 IP 172.16.20.115.20000 > 172.16.20.113.36494: UDP, length 333
(a 90001 ms delay)
在服务器机器上,测试程序输出为:
rich-ova5:~/UDPTest2 # java -cp . Server
Properties:
-- listing properties --
MinSleepTime=1000
DatagramLength=333
MaxSleepTime=90000
Port=20000
Received packet.
Delaying for 3000 ms
Sending packet.
Received packet.
Delaying for 6000 ms
Sending packet.
Received packet.
Delaying for 12000 ms
Sending packet.
Received packet.
Delaying for 24000 ms
Sending packet.
Received packet.
Delaying for 48000 ms
Sending packet.
Received packet.
Delaying for 90000 ms
Sending packet.
Received packet.
Delaying for 90000 ms
Sending packet.
Received packet.
Delaying for 90000 ms
Sending packet.
这是客户端来源:
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;
import java.util.Random;
public class Client {
private static final String CONFIG_FILE = "client.conf";
private int datagramLength;
private boolean debug;
private InetAddress server;
private int serverPort;
private int timeout;
private int loops;
public static void main(String[] arg) throws Exception {
Client c = new Client();
c.go();
}
private void go() throws Exception {
readClientConfig();
Random rand = new Random(System.currentTimeMillis());
System.out.println("UDP socket timeout is " + timeout + " ms");
byte[] referenceData = new byte[datagramLength];
byte[] sentData = new byte[referenceData.length];
int receiveErrors = 0;
int receiveSuccess = 0;
int sendErrors = 0;
int sendSuccess = 0;
for (int i = 0; i < loops; i++) {
long sendTime = 0;
long receiveTime = 0;
rand.nextBytes(referenceData);
System.arraycopy(referenceData, 0, sentData, 0, referenceData.length);
DatagramSocket serverSock = new DatagramSocket();
serverSock.setSoTimeout(timeout);
DatagramPacket datagram = new DatagramPacket(sentData, sentData.length, server, serverPort);
try {
System.out.println("Sending packet " + (i + 1) + " of " + loops);
serverSock.send(datagram);
sendSuccess++;
} catch (Exception e) {
System.out.println("Error sending: " + e.getMessage());
e.printStackTrace();
sendErrors++;
continue;
}
sendTime = System.currentTimeMillis();
try {
serverSock.receive(datagram);
System.out.println("Received packet " + (i + 1) + " of " + loops);
receiveSuccess++;
} catch (Exception e) {
receiveErrors++;
System.out.println("Error receiving: " + e.getMessage());
e.printStackTrace();
}
serverSock.close();
receiveTime = System.currentTimeMillis();
System.out.println("Round-trip time: " + (receiveTime - sendTime) + " ms");
byte[] receivedData = datagram.getData();
if (receivedData.length != referenceData.length) {
System.out.println("Mismatched packet length.");
sendErrors++;
}
for (int j = 0; j < datagramLength; j++) {
if (referenceData[j] != receivedData[j]) {
System.out.println("Mismatched packet contents.");
sendErrors++;
}
}
System.out.println();
}
System.out.println("Send successes: " + sendSuccess);
System.out.println("Send errors: " + sendErrors);
System.out.println();
System.out.println("Receive successes: " + receiveSuccess);
System.out.println("Receive errors: " + receiveErrors);
}
private void readClientConfig() throws IOException {
boolean hasError = false;
String val;
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(CONFIG_FILE);
prop.load(fis);
val = prop.getProperty("Server");
if (val == null) {
System.out.println("Error reading 'Server': missing value");
hasError = true;
} else {
try {
server = InetAddress.getByName(val);
} catch (UnknownHostException e) {
System.out.println("Error reading 'Server': " + e.getMessage());
hasError = true;
}
}
val = prop.getProperty("ServerPort", "3000");
try {
serverPort = Integer.parseInt(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'ServerPort': " + e.getMessage());
hasError = true;
}
val = prop.getProperty("DatagramLength", "200");
try {
datagramLength = Integer.parseInt(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'DatagramLength': " + e.getMessage());
hasError = true;
}
// Time out in milliseconds.
val = prop.getProperty("Timeout", "3000");
try {
timeout = Integer.parseInt(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'Timeout' value.");
hasError = true;
}
// Number of loops to perform.
val = prop.getProperty("Loops", "1");
try {
loops = Integer.parseInt(val);
} catch (NumberFormatException nfe) {
System.out.println("Error reading 'Loops' value.");
hasError = true;
}
val = prop.getProperty("EnableDebug", "yes");
debug = val.equalsIgnoreCase("yes");
System.out.println("Properties:");
prop.list(System.out);
System.out.println();
if (hasError) {
System.out.println("There are errors - fix them and restart the server.");
System.exit(1);
}
}
}
和服务器来源:
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Properties;
public class Server {
private static final String CONFIG_FILE = "server.conf";
private int datagramLength;
private boolean debug;
private int port;
private long initialDelay;
private long maxDelay;
public static void main(String[] arg) throws Exception {
Server s = new Server();
s.go();
}
private void go() throws Exception {
readServerConfig();
DatagramSocket sock = new DatagramSocket(port);
sock.setSoTimeout(0);
byte[] in = new byte[datagramLength];
DatagramPacket datagram = new DatagramPacket(in, datagramLength);
// Loop with exponentially-increasing delays between receive
// and reply (up to the specified maximum delay).
long delay = initialDelay;
while (true) {
sock.receive(datagram);
System.out.println("Received packet.");
System.out.println("Delaying for " + delay + " ms");
Thread.sleep(delay);
System.out.println("Sending packet.");
datagram.setSocketAddress(datagram.getSocketAddress());
datagram.setPort(datagram.getPort());
sock.send(datagram);
System.out.println();
delay *= 2;
if (delay > maxDelay) {
delay = maxDelay;
}
}
}
private void readServerConfig() throws IOException {
boolean hasError = false;
String val;
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(CONFIG_FILE);
prop.load(fis);
val = prop.getProperty("Port", "3000");
try {
port = Integer.parseInt(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'Port' value: " + e.getMessage());
hasError = true;
}
val = prop.getProperty("DatagramLength", "200");
try {
datagramLength = Integer.parseInt(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'DatagramLength' value: " + e.getMessage());
hasError = true;
}
val = prop.getProperty("StartSleepTime", "3000");
try {
initialDelay = Long.parseLong(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'StartSleepTime' value: " + e.getMessage());
hasError = true;
}
val = prop.getProperty("MaxSleepTime", "60000");
try {
maxDelay = Long.parseLong(val);
} catch (NumberFormatException e) {
System.out.println("Error reading 'MaxSleepTime' value: " + e.getMessage());
hasError = true;
}
val = prop.getProperty("EnableDebug", "yes");
debug = val.equalsIgnoreCase("yes");
System.out.println("Properties:");
prop.list(System.out);
System.out.println();
if (hasError) {
System.out.println("There are errors - fix them and restart the server.");
System.exit(1);
}
}
}
和client.conf:
# Server address
Server = rich-ova5.teak.eng
# Server port number.
ServerPort = 20000
# This is the length of the data to send.
# It must match the server's size.
DatagramLength = 333
# Number of times to run the client.
Loops = 8
# Client time out period in milliseconds.
Timeout = 180000
最后,server.conf:
# Server port number.
Port=20000
# Length of the datagram.
# It must match the client's size.
DatagramLength = 333
# Initial sleep time.
MinSleepTime = 1000
# Maximu sleep time. Goes from the MinSleepTime to the
# maximum sleep time.
MaxSleepTime = 90000
最佳答案
如果可能,也许检查 tcpdump 捕获中数据包的 IPv4 TTL(生存时间)。
48 秒后,由于 TTL,数据包可能会被接收方的 IP 堆栈接收但被丢弃。
另请参阅有关更改 TTL 的答案(它表示它仅适用于多播套接字,但无论如何都被接受):Java control IP TTL?
关于java - 为什么 Java 看不到 tcpdump 显示的传入 UDP 数据包已收到?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8527111/
如何告诉tcpdump解析名称并保留未解析的端口号? 来自人: -n Don’t convert host addresses to names. This can be used to a
我正在使用 tcpdump 通过 wlan0 收集数据包数据。但是我发现很多数据包的长度为 0,如下图所示。嗯,长度为 0 的数据包...... tcpdump 可靠还是我错过了什么? 最佳答案 好的
运行“tcpdump -w 1.pcap”时需要限制文件大小。我尝试使用键“-C”来执行此操作,但是当我添加它时,我收到错误“权限被拒绝”。所以: > sudo tcpdump -w 1.pcap t
我正在通过网络适配器捕获 tcp/udp 数据包,并尝试分析数据包以获得一些统计指标,例如带宽速率或协议(protocol)效率。无论如何,我需要使用一些 CLI 工具来监视特定链路(源、目标、端口,
使用 tcpdump 在接口(interface)上捕获 LLDP 数据包的格式是什么? 我尝试了以下格式,但它不起作用: tcpdump -w test.pcap -i eth0 lldp -vv
我想使用 tcpdump 捕获网络流量,如果捕获的数据包增加为 10mb,我想创建另一个文件。我如何使用 tcpdump 安排此操作。请善意地帮助我。谢谢。 最佳答案 tcpdump -W 5 -C
使用 tcpdump 时,我似乎无法看到捕获的所有数据。具体来说,我似乎从帧头丢失了 6 个字节,我想知道是否有人可以解释原因。 为了说明这一点,我在 VMWare 上以仅主机网络配置设置了一个 Ub
我在使用 Android 应用程序中的 TCPDump 时遇到问题。它应该逐行读取 tcpdump 的输出并在我的应用程序中处理它。 问题是: 有时代码工作正常,它会立即读取捕获的数据包。但有时,Re
我都使用过,我的结论是我可以使用 tcpflow 从网页中读取 html 数据,但不能使用 tcpdump 这样做。我得到的最好的结果是一些丑陋的 ASCII 文本,其中有很多句点符号。 我的理解是
我需要在我的 Android 设备上执行 tcpdump 跟踪。 我的设置: 将tcpdump文件推送到sdcard adb push filepath/tcpdump /sdcard/tcpdump
我的电脑上有两个网络接口(interface)。 netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-
Linux中是否有诸如tcpdump之类的实用程序来捕获通过RDMA channel 传输的流量? (Infiniband/RoCE/iWARP) 最佳答案 旧线程,但仍然: 正如Roland指出的那
我有一个巨大的pcap文件(100GB),我对一小部分数据包感兴趣,我知道这些数据包的数量为5,000,000至5,000,020。 如何使用tcpdump读取pcap文件,按数据包编号(或范围)过滤
如何使用 tcpdump 捕获以太网帧并显示本地 PC 使用 UDP、ARP 和 ICMP 协议(protocol)之一发送或接收的任何帧。 我正在尝试这个命令: sudo tcpdump -e ud
我正在使用 tcpdump 捕获网络数据包,当我开始丢弃数据包时遇到问题。我运行了一个通过网络快速交换数据包的应用程序;导致网络带宽较高。 >> tcpdump -i eno1 -s 64 -B 91
是否可以指定tcpdump 测量接收和发送数据包的时间?我知道命令 tcpdump -c 100 指定 tcpdump 在收到 10 个数据包后应该停止。我想指定 tcpdump 在例如 5 分钟后停
运行以下命令时出现错误: sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump* 这提供了以下错误: Failed to set cap
我可以为dst指定1个以上的tcpdump IP地址吗? 如果没有,如果我只想要两个特定目的地的流量,该如何很好地过滤信息? 非常感谢你! 最佳答案 是的,您可能有一个过滤器,其中包含多个通过“或”连
我正在寻找在 openwrt 上运行的 tcpdump 二进制文件。该网站仅显示必须构建的源代码。有人指向我包含预构建二进制文件的位置吗?谢谢。 最佳答案 我建议建立一个工作存储库,即: https:
在服务器 # nc -lp 2424 hi server hi client 1 2 3 在客户端 ➜ ~ nc 139.224.xxx.xx 2424 hi server hi client 1
我是一名优秀的程序员,十分优秀!