8
\$\begingroup\$

I'm writing a simple remote PC app (mouse-keyboard). Android is client and is connect with WiFi to Java PC Server. I'm using TCP but I see a bit of latency compared to other remote apps. Then I used UDP and didn't see any latency or wrong data. UDP look like it's working well. I'm sending a String to Server like these: "a","B","2". Can I use UDP for keyboard remoting?

Client on Android (TCP):

Sending to Server a String method like these("a","C","5"):

public void commandto(String sip, int port ,String byt) {

try
{
    Socket sockClient = new Socket();
    sockClient.connect(new InetSocketAddress(sip,port),9000);       

    //os= new DataOutputStream(sockClient.getOutputStream());
    //OutputStream os = sockClient.getOutputStream();

    PrintWriter out = new PrintWriter(new BufferedWriter(new   OutputStreamWriter(sockClient.getOutputStream())),true);
    out.println(byt);
    out.flush();
    Log.w("Client", "Client sent message");
  sockClient.close();
 }catch (final UnknownHostException e)
 {
//

}catch (final IOException e)
{
  //

 }
}

TCP Server code:

private void cAccept (int portt)  throws AWTException {

    try{
        ss = new ServerSocket(portt);

    }catch (IOException e){
        lblInf.setText("Could not listen on port :"+portt+" "+e.getMessage());
    }

    lblInf.setText("Server is started!");

}

    while(true){
    try{

        s = ss.accept();
        br = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String command =br.readLine();
         System.out.println(command+"\n");
         if(command!=""){
             type(command);
         }
                s.close();
        br.close();

    }catch (IOException e){
        try {

                if(s!=null)
                s.close();
                if(br!=null)
                br.close();

        } catch (IOException es) {
            // TODO Auto-generated catch block
            es.printStackTrace();
        } 
         lblInf.setText("Server is stopped!");
         lblInf2.setText("");

        }
    }
}

Start Server Button code:

  btnStart.addActionListener(new ActionListener()
   {
      public void actionPerformed(ActionEvent e)
     {
         btnStart.setEnabled(false);
        btnStop.setEnabled(true);

          thread = new Thread() {
              public void run(){

                  try {
                    cAccept(9512);
                } catch (AWTException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }    

              }

            };
         thread.start();


}    });

As I've said, I especially see better latency for upper case. If I use UDP, using the following code.

UDP Client sending a String...

  private void runUdpClient(String a)  {

  DatagramSocket ds = null;
  try {
 ds = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName("192.168.2.100");
DatagramPacket dp;
dp = new DatagramPacket(a.getBytes(), a.length(), serverAddr, 9512);
ds.send(dp);
 } catch (SocketException e) {
  e.printStackTrace();
 } catch (UnknownHostException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (Exception e) {
  e.printStackTrace();
}  finally {
 if (ds != null) {
     ds.close();
  }
}
}

UDP server:

 private void runUdpServer() {
  while(true){
 String lText;
 byte[] lMsg = new byte[1000];
 DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
 DatagramSocket ds = null;
 try {
    ds = new DatagramSocket(9512);
    //disable timeout for testing
    //ds.setSoTimeout(100000);
    ds.receive(dp);
    lText = new String(lMsg, 0, dp.getLength());
    if(lText!=""){
         type(lText);
          System.out.println(lText);
     }


    } catch (SocketException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
   } finally {
    if (ds != null) {
        ds.close();
    }
 }
  }
 }

How can I improve the speed? Or should I continue with UDP? If you have any idea or something, I would like to hear it.

EDİT 1 :

I've changed somethings for this answer.

"Then, when I look at your code, i see that you are creating a new TCP socket for every single character that you send."

public class TCPclient extends Activity {

Socket sockClient; 
 PrintWriter out;
.
.
.

}

and method

    public void commandto(String sip, int port ,String byt) {

try
{   
        sockClient = new Socket();
        .
         .
       out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sockClient.getOutputStream())),true);
    ...
 }
 }

and I've changed it with this on TCP Server side.

    String command =br.readLine();
         System.out.println(command+"\n");
         if(command!=""){
             type(command);
         }

-

   private void cAccept (int portt)  throws AWTException {
   .
   .
   .
   while(true){
    ....

   command =br.readLine();
 System.out.println(command+"\n");
 type(command)
       }
    }

Already I've using these on TCP Server

     public class TCPServer extends JFrame{ 
    ...
    private ServerSocket ss= null;
private Socket s =null;
private BufferedReader br=null;
    ...
     }

Now is looking better. But I see a bit of latency compared to other remote apps. How can I more improve it for latency?

\$\endgroup\$
  • 3
    \$\begingroup\$ From the looks of it, proper indentation should come before everything else. This looks quite messy and should really be improved. \$\endgroup\$ – Jamal Mar 12 '14 at 20:24
  • \$\begingroup\$ It is messy I know it. But what can I do for improve it? Why I'm getting latency , I think It's not about messy. Is it possible sending a string , server side or key press? \$\endgroup\$ – user38652 Mar 12 '14 at 20:41
  • 1
    \$\begingroup\$ I'm not familiar with any of the specifics. I've just noticed this aspect, which I still believe is important, even though it's not related to latency. And if you're aware it's messy, then you should clean it up. That'll make your code much easier to read and will be more attractive for reviewers. \$\endgroup\$ – Jamal Mar 12 '14 at 20:53
  • \$\begingroup\$ Yes my codes not clean and unreadably. I'm now testing on this app. If I didn't get latency, of course I'll do setting the app with OOP. \$\endgroup\$ – user38652 Mar 12 '14 at 21:01
5
\$\begingroup\$

I would expect UDP to be slightly faster in latency than TCP, but not so that you could measure it by 'feel'. I would expect the differences to be in the order of micro-seconds.

Then, when I look at your code, i see that you are creating a new TCP socket for every single character that you send.

This is a real problem, and is not the way that TCP is supposed to be used.

TCP is a stateful connection, and needs a fair amount of communication to ensure both sides of the socket are are steady and reliable state. This overhead is what is creating your latency each time you connect.

With TCP connections it is standard to connect the socket at the beginning of your application, and to then leave it connected the whole time. All you need to do is send a byte each time a key is pressed, rather than re-creating the entire connection.

With UDP, it is stateless, and there is no guarantee on delivery. it is also much faster/easier to create connections, because there is no need for negotiation.

On the other hand, if the key-stroke does not get through, it won't show up on the screen either, and the user can be the 'resend' mechanism.... if the user types a key, and it does not show up on the screen, the user can type it again.

So, UDP may be a useful protocol for you, and you may want to keep it... but... the reason it is so much faster than TCP is because you are using TCP completely against the way it is designed to be used.

\$\endgroup\$
  • \$\begingroup\$ I've edited my question, looking your answer. \$\endgroup\$ – user38652 Mar 13 '14 at 11:15
  • \$\begingroup\$ "rolfl" Can you check my new edit? I have see same problem. \$\endgroup\$ – user38652 Mar 13 '14 at 16:55
  • \$\begingroup\$ @sallamaniaa - come join us in the 2nd Monitor chat room, go through some things. \$\endgroup\$ – rolfl Mar 13 '14 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy