2013-03-14 67 views
1

我不知道这是否真的有问题,但我创建了一个应用程序,它通过wifi或便携式热点在计算机上控制鼠标光标。问题出在这里:当我使用wifi接入点连接我的电脑和我的android设备时,光标移动不如我将电脑连接到android设备的便携式热点时那样流畅。我尝试了两种不同的android手机,并得到同样的问题。 下面是我在应用程序中使用的TCP代码: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文件中。

回答

1

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

实际上,所谓的nagle算法通常会增加延迟以提高批量效率。您可能有能力在某些系统上禁用它,但不能在其他系统上禁用它 - 而且通常您需要在连接的两端都这样做,以避免由此产生的延迟。

此外,WiFi网络不保证延迟,所以你可以看到,差异很大。诸如接入点的实施细节可能会改变效率,射频环境也会如此 - 我看到该国的延迟低于大城市中间的延迟。此外,当您将手机用作接入点时,您将限制所需的WiFi行程数 - 而不是手机接入点计算机,它就变成了电话计算机。

所以你可能看的东西:

  • 切换到UDP而不是TCP,并实现自己的低延迟可靠性(ACK /重发)机制
  • 选择没有其他用户WiFi信道(如果可能的话)
  • 如果你必须留在TCP,禁用的Nagle
  • 使用手机接入点模式(尽管这也许是不可取的,因为你可能不希望PC的其他流量走那条路)
  • 使用蓝牙而不是WiFi
+0

感谢您的回答克里斯。出于某种原因,我可以使用一些建议,如切换到UDP或禁用Nagle的算法,或使用手机的热点。出于某些原因,我为那些拥有自己的wifi调制解调器或WiFi接入点的人创建了应用程序,因为当我在手机的热点中使用该应用程序时,手机在一段时间后会过热。 – JozackOverFlow 2013-03-14 15:32:21

1

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

+0

你刚刚解决了我一直在苦苦挣扎的问题,谢谢! – Eran 2015-02-22 19:45:06

+0

@不用客气! – JozackOverFlow 2015-02-25 02:33:47