In my Java application there is a Socket open and data is being read from its InputStream.
In optimal conditions each packet that comes in results in a call to read() returning its application layer data. This is what I am trying to get – one ‘message’ per packet.
However, it is possible that data gets buffered in the socket based on what getReceiveBufferSize() returns. If this happens and the stream is read from, there may be data from multiple packets sitting there.
Is there another method to get data from individual packets, or does that violate layers of abstraction?
Alternatively, is it possible to set some sort of delimiter for when data gets appended to the buffer? Or is that something at the platform level that cannot be done?
Here is some example code to demonstrate what I am doing:
import java.io.InputStream;
import java.net.Socket;
public class Belnets {
public Belnets() {
try{
Socket s = new Socket("address", 23);
System.out.println("platform will buffer this much: "+s.getReceiveBufferSize());
InputStream sin = s.getInputStream();
byte[] data = new byte[1024];
int c;
while(true){
c = sin.read(data);
for(int i=0; i<c; i++){
System.out.print((char)data[i]);
}
System.out.println("=END OF READ=");
//if you dont do this, read() seems to return once for each packet as this loop
//appears to be running fast enough to keep up with the rate of data that comes in.
//otherwise data gets buffered and you get multiple packets worth of data before seeing
//=END OF READ=
Thread.sleep(1000);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
new Belnets();
}
}
The Java API doesn’t provide any way to read TCP packets. It’s stream-based, and you have absolutely no way to read one packet at a time.
If you want to send and receive multiple messages, you need to implement an application-level protocol, which might use a specific delimiter between messages, or send the length of a message followed by the message body itself, for example.