tags:

views:

165

answers:

4

I have written a socket program in Java. Both server and client can sent/receive data to each other. But I found that if client sends data to server using TCP then internally TCP sends acknowledgement to the client once the data is received by the server. I want to detect or handle that acknowledgement. How can I read or write data in TCP so that I can handle TCP acknowledgement.

Thanks Sunil Kumar Sahoo

A: 

Any data sent over a TCP socket is acknowledged in both directions. Data sent from client to server is the same as data sent from server to client as far as TCP wire communications and application signaling.

Is it possible that the client's message is larger than the server's response so the buffering is getting in the way of the response but not the initial request? Have you tried to use non-blocking sockets?

You might want to take a look at the NIO code if you have not already done so: http://java.sun.com/j2se/1.4.2/docs/guide/nio/

Gray
Incorrect, see my answer, and NIO doesn't help in this matter in the slightest.
EJP
I'm sorry, how is it incorrect? What is the difference between a byte sent from the client to the server versus from server to client?I suspect that the question is confusing TCP sockets with (as you allude to) buffering and other issues which is the reason I mention non-blocking and NIO.
Gray
+2  A: 

This is simply not possible, even if you were programming in C directly against the native OS sockets API. One of the points of the sockets API is that it abstracts this away for you.

The sending and receiving of data at the TCP layer doesn't necessarily correlate with your Java calls to send or receive data. The data you send in one Java call may be broken into several pieces which may be buffered, sent and received independently, or even received out of order.

See here for more discussion about this.

Eric Petroelje
A: 

I want to detect or handle that acknowledgement.

There is no API for receiving or detecting the ACKs at any level above the protocol stack.

Rethink your requirement. Knowing that the data has got to the server isn't any use to an application. What you want to know is that the peer application has received it, in which case you have to get the peer application to acknowledge at the application protocol level.

EJP
"TCP/IP practices 'selective ACK'. Not every byte/packet/segment is acknowledged." As I read it, this is incorrect. SACK is about informing the sender that packets ahead of missing packets have been received so only the missing packets need to be retransmitted. If a packet arrives on the receiver, it _will_ be acknowledged -- either in a specific ack or as part of a cumulative ack.
Gray
Agreed, amending. Remainder of my answer still applies.
EJP
A: 

This is not possible in pure Java since Java's network API all handles socket, which hides all the TCP details.

You need a protocol that can handle IP-layer data so you can get TCP headers. DLPI is the most popular API to do this,

http://www.opengroup.org/onlinepubs/9638599/chap1.htm

Unfortunately, there is not Java implementation of such network. You have to use native code through JNI to do this.

ZZ Coder