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

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -