TCP数据传输不好

时间:2013-03-14 14:22:44

标签: android tcp

我不知道这是否真的有问题,但我创建了一个应用程序,通过wifi或便携式热点控制计算机上的鼠标光标。这就是问题:当我将我的电脑和我的Android设备连接到wifi接入点时,光标移动并不像我将电脑连接到Android设备的便携式热点时那么顺畅。我尝试了两个不同的Android手机,并遇到了同样的问题。 以下是我在应用程序中使用的TCP代码:

    @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();
    }
}

以下是我在服务器上使用的TCP代码

    @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
    }
}

原谅我因为一些细节原因​​我不能在我的java文件中发布整个代码。

2 个答案:

答案 0 :(得分:1)

您不应该期望TCP的低延迟行为,因为它不是为此目的而设计的。

事实上,称为nagle算法的东西通常会增加延迟,以提高批量效率。您可以在某些系统上禁用它,但不能在其他系统上禁用它 - 通常您需要在连接的两端执行此操作以避免导致延迟。

此外,wifi网络无法保证延迟,因此您可以看到变化很大。像接入点的实施细节这样的事情可以改变效率,RF环境也是如此 - 我看到该国的延迟远远低于大城市中部。此外,当您使用手机作为接入点时,您可以限制所需的无线网络旅行次数 - 而不是电话接入点计算机,它只是手机电脑。

所以你可能会看到的东西:

  • 切换到UDP而不是TCP,并实现自己的低延迟可靠性(确认/重发)机制
  • 选择没有其他用户的wifi频道(如果可能)
  • 如果您必须使用TCP,请禁用nagle
  • 在接入点模式下使用手机(虽然这可能是不受欢迎的,因为您可能不希望PC的其他流量通过这种方式)。
  • 使用蓝牙而不是wifi

答案 1 :(得分:0)

我尝试使用UDP方法,但客户端有时会丢失数据包,这会导致我的服务器出现一些错误。 几个小时后,我找到了一个适合我的解决方案,我不确定它是否适合其他人。 对客户端套接字和服务器套接字使用setTcpNoDelay()。