patternjavaMinor
Latency problem for keyboard remoting from Android phone
Viewed 0 times
fromproblemandroidforphonekeyboardlatencyremoting
Problem
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"):
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
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
Solution
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.
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.
Context
StackExchange Code Review Q#44189, answer score: 5
Revisions (0)
No revisions yet.