5

My goal is to send a TCP packet with empty data field, in order to test the socket with the remote machine.

I am using the OutputStream class's method of write(byte[] b). my attempt:

outClient = ClientSocket.getOutputStream();
outClient.write(("").getBytes());

Doing so, the packet never show up on the wire. It works fine if "" is replaced by " " or any non-zero string.

I tried jpcap, which worked with me, but didn't serve my goal. I thought of extending the OutputStream class, and implementing my own OutputStream.write method. But this is beyond my knowledge. Please give me advice if someone have already done such a thing.

JoeAngel
  • 51
  • 1
  • 3
  • Just for the sake of curiosity, why do you want to do this? – Spencer Ruport May 21 '12 at 22:41
  • 1
    I'm developing a TCP proxy and I want it to quickly detect silently dropped connections to clean up for new connections. So I don't think the TCP keepalive will serve the 'quickly' purpose. I hope you can help! – JoeAngel May 21 '12 at 22:48
  • 1
    Well I have a feeling you'll be up the creek on this one. I'd have to look at the spec but I'm willing to bet there's no defined behavior for this which means not only Java but even the hardware or hardware drivers may simply decide not to send your "packet" since it's empty at the manufacturers discretion. – Spencer Ruport May 21 '12 at 23:15
  • But as i mentioned in the question. I could send the packet using jpcap. But it injects the packets, which is not helpful for me. So your assumption regarding the hardware maybe is not correct. Also the TCP header says, "data if any". – JoeAngel May 21 '12 at 23:19
  • 1
    I think you need to understand the implementation of TCP in depth, so you should better check out socket programming in C (BSD Sockets on *nix systems), then study on raw sockets. With raw sockets, you can build up custom Transport Layer Packets, it's a good study to read RFC for TCP and building customs TCP packets with raw sockets. – Levent Divilioglu Mar 30 '16 at 01:32
  • TCP's data unit is called segment and not packet. Could you use the correct terminology in your question and title – darw Jan 01 '21 at 17:42

2 Answers2

3

If you just want to quickly detect silently dropped connections, you can use Socket.setKeepAlive( true ). This method ask TCP/IP to handle heartbeat probing without any data packets or application programming. If you want more control on the frequency of the heartbeat, however, you should implement heartbeat with application level packets.

See here for more details: http://mindprod.com/jgloss/socket.html#DISCONNECT

Hakan Serce
  • 11,198
  • 3
  • 29
  • 48
  • yes .. I should implement it. Sending an, in sequence, zero-data packet will require an ACK from the other end, which can help me know if the connection is still working or not. Zero-data, so that no modification to the remote host is required. – JoeAngel May 21 '12 at 23:26
  • The site you linked to is a notorious source of misinformation, and what is worse he does not accept corrections. I've tried. For example: "I have found Java’s connection continuity testing to be less than 100% reliable". Java *doesn't have any continuity testing at all:* it is done by the operating system's TCP stack. I told him all that about eight years ago. – user207421 May 22 '12 at 01:27
-2

There is no such thing as an empty TCP packet, because there is no such thing as a TCP packet. TCP is a byte-stream protocol. If you send zero bytes, nothing happens.

To detect broken connections, short of keepalive which only helps you after two hours, you must rely on read timeouts and write exceptions.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    I said zero-data packet, in the question description. It's is possible to send such packet and i did it using a special package called jpcap. And the remote host acknowledged it. So why do you say there is no such a thing?? I want to do the same thing but using the JDK itself (without jpcap). Do you know how? – JoeAngel May 22 '12 at 12:49
  • @JoeAngel There is no such thing via write("").getBytes(), OK? Of course there are SYN, ACK, RST, and FIN packets, and the subterfuge that TCP keepalive engages in by sending an ACK with the wrong sequence number. There is also hacking with 'packages called JPcap'. My answer was confined to the bounds of sanity frankly. – user207421 May 23 '12 at 10:36
  • NB There is nothing about JPcap in your question, but there is about `write(("").getBytes())`, which is what I answered. – user207421 May 05 '17 at 04:43