JozackOverFlow
JozackOverFlow

Reputation: 267

TCP data transferring is not good

I don't know if this really is a problem, but I created an app which controls the mouse cursor on computer through wifi or portable hotspot. Here's the problem: when I connect my pc and my android device with a wifi accesspoint, the cursor movements is not as smooth as when I connect my pc to the android device's portable hotspot. I tried with two different android phone and got the same problem. Here are the TCP codes I use on the app:

    @Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction();

    switch (action) {
    case MotionEvent.ACTION_DOWN:

        xStart = event.getRawX();
        yStart = event.getRawY();
        if (mess.equals("click")) {
            mess="leftdown";
        }
        break;

    case MotionEvent.ACTION_MOVE:
        xMove = event.getRawX();
        yMove = event.getRawY();
        distanceX = (xStart - xMove);
        distanceY = (yStart - yMove);
        sendCmd(distanceX, distanceY);
        xStart = xMove;
        yStart = yMove;
        mess="move";
        sendMess(mess);
        break;

    case MotionEvent.ACTION_UP:
        break;
    }
    return detector.onTouchEvent(event);
}

void sendCmd(float distanceX, float distanceY) {
    try {
        out.writeFloat(distanceX);
        out.writeFloat(distanceY);

    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

void sendMess(String mess) {
    try {
        out.writeUTF(mess);

    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

And here are the TCP codes I used on the server

    @Override
public void run() {

    // System.out.println("Connected");
    // pixel, velocity

    float x = 0, y = 0;
    try {

        Robot mouse = new Robot();
        PointerInfo a;

        Point b;
        String mess;
        int xx, yy;

        DataInputStream in = new DataInputStream(server.getInputStream());
        x = in.readFloat();
        y = in.readFloat();
        mess = in.readUTF();
        System.out.println(x + "-" + y);
        if (mess.equals("click")) {
            mouse.mousePress(InputEvent.BUTTON1_MASK);
            mouse.mouseRelease(InputEvent.BUTTON1_MASK);

        } else if (mess.equals("scroll")) {

        } else if (mess.equals("leftdown")) {
            mouse.mousePress(InputEvent.BUTTON1_MASK);
        } else if (mess.equals("leftup")) {
            mouse.mouseRelease(InputEvent.BUTTON1_MASK);
        } else if (mess.equals("right")) {
            mouse.mousePress(InputEvent.BUTTON3_MASK);
            mouse.mouseRelease(InputEvent.BUTTON3_MASK);
        } else if (mess.equals("move")) {
            a = MouseInfo.getPointerInfo();
            b = a.getLocation();
            xx = (int) b.getX();
            yy = (int) b.getY();
            mouse.mouseMove(xx - (int) x, yy - (int) y);
            mouse.delay(7);
        }
    } catch (Exception e) {
        // TODO: handle exception
    }
}

Forgive me because of some particulars reason I can't post the whole code in my java files.

Upvotes: 1

Views: 315

Answers (2)

Chris Stratton
Chris Stratton

Reputation: 40407

You should not expect low-latency behavior of TCP, as it is not designed for that purpose.

In fact, something called the nagle algorithm often increases latency in an effort to improve bulk efficiency. You may have the ability to disable it on some systems, but not on others - and often you will need to do so on both ends of the connection to avoid the resulting delays.

Also, wifi networks make no guarantees of latency, so you can see that vary a lot. Things like implementation details of the access point can change efficiency, as can the RF environment - I've seen far lower latencies out in the country than in the middle of a large city. Also, when you use your phone as the access point, you limit the number of wifi trips required - instead of phone-access point-computer, it becomes just phone-computer.

So the things you might look at:

  • Switch to UDP instead of TCP, and implement your own low-latency reliability (ack/resend) mechanism
  • Choose a wifi channel without other users (if possible)
  • If you must stay with TCP, disable nagle
  • Use the phone in access point mode (though that is perhaps undesirable, as you may not want the PC's other traffic to go that way)
  • Use bluetooth instead of wifi

Upvotes: 1

JozackOverFlow
JozackOverFlow

Reputation: 267

I tried using UDP method but the packet is sometimes missing from the client and it caused some errors in my server. After a few hours, I've found a solution that works for me, I'm not sure it works well with others. Use the setTcpNoDelay() for both client socket and server socket.

Upvotes: 0

Related Questions