Java nio read bytebuffer from channel -
my issue how receive data server example "cutting" in parcels of 1024 bytes, cause when answer comes server in packets 2 parts don't know how solve that. ex. when first packet arrives size informed server 1988 , received 1444, it's ok, when second packet arrives size informed 808333347 , received 540, sum of 1444 + 540 = 1984 right. don't know number 808333347 coming from. i'm googling solution , teachs using udp , need tcp/ip connection. please me, solve that.
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 = 0; < 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 { { 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 function 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 ugly now.
you can't control how data arrives on tcp connection, either end. can arrive byte @ time or in other quanta size of data. have loop @ receiving end until have need. need use same read buffer size of socket can accumulate data loop, , preserve data might belong subsequent message.
the 'size informed' cannot huge state. results bug. getting out of sync.
Comments
Post a Comment