使用Java发送一个零数据的TCP/IP数据包

5
我的目标是发送一个空数据字段的TCP数据包,以便与远程机器测试套接字。我正在使用OutputStream类的write(byte[] b)方法。我的尝试:
outClient = ClientSocket.getOutputStream();
outClient.write(("").getBytes());

这样做,数据包就不会出现在网络上。如果将“”替换为“ ”或任何非零字符串,则可以正常工作。
我尝试过jpcap,它可以与我一起使用,但并没有达到我的目标。 我考虑扩展OutputStream类,并实现自己的OutputStream.write方法。但这超出了我的知识范围。如果有人已经完成了这样的事情,请给我建议。

只是出于好奇,你为什么想要这样做? - Spencer Ruport
1
我正在开发一个TCP代理,希望它能快速检测到静默丢失的连接并清理出新的连接。因此,我认为TCP keepalive不会起到“快速”的作用。希望你能帮忙! - JoeAngel
1
我有一种感觉,你在这件事上可能会陷入困境。我得看一下规格说明,但我敢打赌,这个问题没有定义的行为,这意味着不仅是Java,甚至硬件或硬件驱动程序也可能会根据制造商的决定选择不发送你的“数据包”,因为它是空的。 - Spencer Ruport
但正如我在问题中提到的那样,我可以使用jpcap发送数据包。但它注入数据包,对我来说没有帮助。所以你关于硬件的假设可能是不正确的。此外,TCP头部中说:“如果有的话,就是数据”。 - JoeAngel
1
我认为你需要深入了解TCP的实现,所以最好查看C语言中的套接字编程(*nix系统上的BSD套接字),然后学习原始套接字。使用原始套接字,您可以构建自定义传输层数据包,阅读TCP的RFC并使用原始套接字构建自定义TCP数据包是一个很好的学习方法。 - Levent Divilioglu
TCP的数据单元称为“段”而不是“包”。您能否在您的问题和标题中使用正确的术语? - darw
2个回答

3
如果您只想快速检测已被静默丢弃的连接,可以使用 Socket.setKeepAlive( true )。此方法要求TCP/IP处理心跳探测,而无需任何数据包或应用程序编程。但是,如果您想更好地控制心跳频率,则应使用应用程序级别的数据包实现心跳控制。更多详细信息请查看这里:http://mindprod.com/jgloss/socket.html#DISCONNECT

是的,我应该实现它。按顺序发送零数据包将需要另一端的ACK,这可以帮助我知道连接是否仍在工作中。零数据,因此不需要对远程主机进行修改。 - JoeAngel
你链接的网站是一个臭名昭著的错误信息来源,更糟糕的是他不接受纠正。我试过了。例如:“我发现Java的连接连续性测试不到100%可靠。” Java根本没有任何连续性测试:它是由操作系统的TCP堆栈完成的。我大约八年前就告诉过他这一点。 - user207421

-2

不存在空的TCP数据包,因为TCP协议本身就不支持空数据包。TCP是一种字节流协议。如果你发送零个字节,什么也不会发生。

要检测断开的连接,除了keepalive之外(只有在两小时后才能帮助您),您必须依赖读取超时和写入异常。


1
我在问题描述中提到了零数据包。使用一个叫做jpcap的特殊包,可以发送这样的数据包,并且远程主机已经确认接收到了它。那么为什么你说这种东西不存在呢? 我想用JDK本身来完成同样的事情(不使用jpcap)。你知道怎么做吗? - JoeAngel
@JoeAngel,通过write(“”)。getBytes()没有这样的东西,好吗?当然有SYN、ACK、RST和FIN数据包,以及TCP keepalive通过发送带有错误序列号的ACK所涉及的欺骗手段。还有使用名为JPcap的“包”进行黑客攻击。坦白说,我的回答是在理智的范围内的。 - user207421
请注意,您的问题中没有关于JPcap的内容,但是在您提问中有关于write(("").getBytes())的部分,这也是我回答的内容。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接