java - How reliable socket stream's flush() is? -
consider (simplified) piece of code:
public class test { // assigned elsewhere inetsocketaddress socketaddress; string sockethost; int socketport; socket socket; int command = 10; int connection_timeout = 10 * 1000; int socket_timeout = 30 * 1000; dataoutputstream dos; datainputstream dis; protected void connect() throws ioexception, interruptedexception { socket.connect(socketaddress != null ? socketaddress : new inetsocketaddress(sockethost, socketport), connection_timeout); socket.setsotimeout(socket_timeout); socket.settcpnodelay(true); } void initializedatastreams() throws ioexception { dos = new dataoutputstream(new bufferedoutputstream(socket.getoutputstream(), socket.getsendbuffersize())); dis = new datainputstream( new bufferedinputstream( socket.getinputstream(), socket.getreceivebuffersize())); } void run() { try { connect(); initializedatastreams(); sendcommand(command, true); sendidandusername(true); sendsyncpreference(true); sendblockedids(true); sendheaders(); // reading 'dis' here // ... } catch (interruptedexception | ioexception e){ /* ... */ } } void sendcommand(int command, boolean buffered) throws ioexception { dos.write(command); if (!buffered) { dos.flush(); } } void sendidandusername(boolean buffered) throws ioexception { sendid(true); // buffered string username = "user name"; dos.writeboolean(username != null); if (username != null) { dos.writeutf(username); } if (!buffered) { dos.flush(); } } void sendid(boolean buffered) throws ioexception { dos.writeutf("user id"); if (!buffered) { dos.flush(); } } void sendsyncpreference(boolean buffered) throws ioexception { boolean fullsync = true; dos.writeboolean(fullsync); if (!buffered) { dos.flush(); } } void sendblockedids(boolean buffered) throws ioexception { set<string> blockedcrocoids = new hashset<>(); objectoutputstream oos = new objectoutputstream(dos); oos.writeobject(blockedcrocoids); if (!buffered) { oos.flush(); } } private void sendheaders() throws ioexception { dos.writeutf("some string"); dos.writeint(123); // other writes... // should flush everything, right? dos.flush(); } }
i left intentionally methods, in case i've made terribly obvious mistake there. when execute test.run(), sometimes (really hard predict when exactly) seems flush() in sendheaders() doesn't work @ all.
server side doesn't receive on serversocket.accept() next 22 seconds (don't ask me number comes from, part of mystery).
the idea wont call flush() on every transmission call once, save bandwidth.
so what's wrong code? how ensure writes stream reliable / immediate server can read asap?
i accept answer "there's nothing wrong", in case must being done in parallel , affecting network stack on android.
edit: server code nothing special:
listeningthread listeningthread = new listeningthread(); listeningthread.start(); listeningthread.join();
and then:
public class listeningthread extends thread { private serversocket serversocket; public listeningthread() { try { // unbound server socket serversocket = new serversocket(); serversocket.setreuseaddress(true); serversocket.bind(new inetsocketaddress(networkutil.app_server_port)); } catch (ioexception e) { log(e); } } @override public void run() { log("run"); while (serversocket.isbound() && !isinterrupted()) { try { socket socket = serversocket.accept(); new commandthread(socket).start(); } catch (ioexception e) { log(e); } } try { serversocket.close(); } catch (ioexception e) { log(e); } } }
and finally:
public class commandthread extends thread { private final socket socket; public commandthread(socket socket) { log("commandthread"); this.socket = socket; } @override public void run() { log("run"); try { socket.setsotimeout(networkutil.socket_timeout); socket.settcpnodelay(true); inputstream = socket.getinputstream(); int cmd = is.read(); // <========= failing switch (cmd) { // handling of command case command: new downloadmessagesthread(socket).start(); break; } } catch (ioexception | sqlexception e) { log(e); } } }
as mentioned in comments, i'd open agree on wrong object streams & co trouble i'm unable reach (again, it's sometimes, it's random...) commandthread's run(). unless i'm missing else, there's no way object streams cause kind of failure.
edit 2: correction: it's not accept() cannot reach, it's first read operation:
03-07 11:22:42.965 00010 commandthread: commandthread
03-07 11:22:42.966 00108 commandthread: run
[... nothing happening ...]
03-07 11:23:04.549 00111 downloadmessagesthread: run
could caused mixing object stream , data stream after all?
you should verify objectoutputstream
creation in sendblockedids
not culprit. i've had protocol "deadlocks" while mixing datastreams , objectstreams, since creation of writer/reader pair of objectstreams implies kind of handshake may fail while mixing streams.
edit: while reading again question, realized had not answered it. yes, reliable. , +1 ejp answer.
Comments
Post a Comment