How to receive the data from server example "cutting" in parcels of 1024 bytes, cause when the answer comes from server in packets like 2 parts I don't know how solve that.
Ex. When the first packet arrives the size informed by the server is 1988 and received is 1444, that it's ok, but when the second packet arrives the size informed is something like 808333347 and received 540, the sum of 1444 + 540 = 1984 that is right. I don't know where this number 808333347 is coming from.
I'm googling for this solution and all then teachs using udp and I need this for a tcp/ip connection.
The class:
public class Connection implements Runnable {
private static Connection instance;
private SocketChannel channel = null;
private int port = 0;
private int service = 0;
private final int SOCKET_TIMEOUT = 15 * 1000;
private final int SOCKET_BYTES = 16 * 1024;
private final Charset CHARSET = Charset.forName("ISO-8859-1");
private String host = null;
private String message = "";
public Connection(String host, String port){
this.host = host;
this.port = Integer.parseInt(port);
}
public static Connection createConnection(String host, String port) {
if(instance == null){
instance = new Conexao(host, port);
}
return instance;
}
public void connect(){
try{
instance.channel = SocketChannel.open();
instance.channel.socket().setSoTimeout(SOCKET_TIMEOUT);
instance.channel.socket().setTcpNoDelay(false);
instance.channel.socket().setKeepAlive(true);
instance.channel.connect(new InetSocketAddress(host, port));
instance.channel.configureBlocking(false);
} catch (IOException ioe){
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
}
@Override public void run() {
if(null != instance.channel){
if(instance.channel.isConnected()){
Log.d(TAG, "CHANNEL CONNECTED = TRUE");
} else {
Log.d(TAG, "CHANNEL CONNECTED = FALSE");
}
} else {
instance.connect();
Log.d(TAG, "CHANNEL CONNECTED");
}
sendMessage();
while(true){
receiveMessage();
}
}
public void sendMessage() {
int size = message.length();
ByteBuffer buffer = ByteBuffer.allocate(4 + 4 + size);
buffer.putInt(service).putInt(size).put(message.getBytes());
buffer.flip();
for(int i = 0; i < size; i++){
try {
instance.channel.write(buffer);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
}
}
public void receiveMessage(){
ByteBuffer buffer = ByteBuffer.allocateDirect(SOCKET_BYTES);
int bytesReaded = 0;
String received = "";
buffer.clear();
try {
do {
bytesReaded = instance.channel.read(buffer);
} while (bytesReaded == 0);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
buffer.flip();
int size = buffer.getInt();
received += CHARSET.decode(buffer);
Log.d(TAG,"SERVIÇE: " + size + "/" + received.length() + " MSG: " + received);
}
public int getService() {
return service;
}
public void setService(int service) {
this.service = service;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
I changed the function like this:
public void receiveMessage(){
ByteBuffer buffer = ByteBuffer.allocateDirect(SOCKET_BYTES);
int bytesReaded = 0;
String received = "";
buffer.clear();
try {
bytesReaded = instance.channel.read(buffer);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
buffer.flip();
if(bytesReaded >= 4){
if(size == 0 && size < 5000) size = buffer.getInt();
received += CHARSET.decode(buffer);
answer += received;
if(size == answer.length()){
Log.d(TAG,"SERVICE: " + size + "/" + answer.length() + " " + answer);
}
}
}
But it's very ugly now.