正在执行一个宠物项目,以便通过android设备为我的计算机创建可工作的鼠标,我在PC上运行了一个python服务器,并且android应用程序向其发送了所需的数据。
我创建此鼠标的想法是使用Motion_Event UP和MOVE在设备屏幕上记录您的手指运动,计算您的上一个和新的x,y坐标之间的差异,并将该差异发送到PC,以便它将鼠标移动到相同的模式
现在我有一些问题,从发送本身到计算,我真的希望你们的意见关于我应该如何更好地执行此算法,或者只是对我的代码做一个不好的实现。
Java的:
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN ){
oldX = (int) event.getX();
oldY = (int) event.getY();
}
else if(event.getAction() == MotionEvent.ACTION_MOVE ){
newX = (int) event.getX();
newY = (int) event.getY();
xDiff = newX - oldX;
yDiff = newY - oldY;
Log.v("xdiff", ""+xDiff);
Log.v("ydiff", ""+yDiff);
oldX = newX;
oldY = newY;
a.mouse(xDiff, yDiff);
}
else if(event.getAction() == MotionEvent.ACTION_UP){
}
return true;
}
socket :
@Override
protected Void doInBackground(Void... params) {
try {
this.sock = new Socket("10.0.0.2", 9871);
outToServer = new DataOutputStream(this.sock.getOutputStream());
}
catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void mouse(int x, int y) {
try {
this.outToServer.writeBytes(""+x+","+y);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
python套接字:
def __init__(self, IP, port):
try:
self.acceptor = socket.socket()
self.acceptor.bind((IP, port))
self.acceptor.listen(1)
except socket.error, e:
print e
def start_server(self):
try:
print "serv up"
self.sock, self.connecting_ip = self.acceptor.accept()
print self.connecting_ip[0] + " connected!"
except socket.error, e:
print e
数据处理本身:
def mouse(self):
try:
while True:
data = self.sock.recv(1024)
if data:
coords = data.split(",")
x = int(coords[0])
y = int(coords[1])
current_x = win32api.GetCursorPos()[0]
current_y = win32apo.GetCursorPos()[1]
win32api.SetCursorPos((current_x+x,current_y+y))
else:
self.sock.close()
except socket.error, e:
print e
我遇到的问题是:
1)而不是像我发送的那样获取数据(“” + x +“,” + y),它将更多的数据加载到缓冲区中,并以x,y,x,y,x,y,x,y的形式显示,x,y,x,y ...
我试图弄乱缓冲区的大小,但是并没有做太多
(请注意,这很奇怪,当我在模拟器上运行应用程序时,我没有收到此错误,并且我将想要的东西完全放入x,y的缓冲区中,但是当我运行时它在我的android设备上(如果很重要,则为SGS2),数据进入掩体并立即发送所有内容)
2)我得到的另一件事是数据被“损坏”或丢失,例如发送“”而不是数字,或者发送了4和-5以4-5(而不是4,-5)发送
总而言之,我敢肯定我在这里主要是在操蛋,我希望有人能阐明我该如何去做。
UDP实现:
@Override
protected Void doInBackground(Void... params) {
try {
this.clientSocket = new DatagramSocket();
this.IPAddress = InetAddress.getByName("10.0.0.2");
this.sendData = new byte[1024];
}
catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void mouse(int x, int y) {
try {
String sentence = "{" + x + "," + y + "}";
this.sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(this.sendData, this.sendData.length, this.IPAddress, 9871);
this.clientSocket.send(sendPacket);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
python udp serv:
import socket
PORT = 9871
IP = socket.gethostbyname(socket.gethostname())
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((IP, PORT))
print "Server %s" % IP
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
if data:
print "received message:", data
else:
print "dead"
最佳答案
TCP是流协议(protocol)。这意味着当您多次send()
(或者在您的情况下为.writeBytes()
)时,不同调用的参数之间没有边界。
例如,当您发送:
send("1,2");
send("-3,4");
send("5,6");
send("-7,8");
然后,这可能会到达另一端,如下所示:
"1,2-3,45,6-7,8"
如果要使用TCP并保留消息之间的边界,则需要在协议(protocol)中添加一层以提供此功能。有两种传统方法可以实现此目的:
在您的情况下,通过简单地添加换行符来选择第一个选项就可以解决问题:
send("1,2\n");
send("-3,4\n");
send("5,6\n");
send("-7,8\n");
这将以类似以下方式到达另一端:
"1,2\n-3,4\n5,6\n-7,8"
阅读时,您可以使用换行符来重建原始消息。
警惕线条不完整。当我们说数据必须以
"1,2\n-3,4\n5,6\n-7,8"
的形式到达时,我们在上面进行了一些简化。它也可能一次到达:"1,2\n-3," // from the first read call
"4\n5,6\n-7,8" // from the second read call
从TCP流读取消息时,需要将读取的内容放入缓冲区。在处理完一条完整的消息之前(或直到某些原因导致您想要完全放弃连接之前),您无法丢弃数据。例如,如果缓冲区以不完整的消息
"-3,"
结尾,那么您需要阅读直到拥有其余消息:"4\n"
。另一种可能合适的解决方案是使用数据报协议(protocol)(例如UDP),其中发送方的消息确实确实与接收方的消息相对应。 (请注意,TCP和UDP之间还有其他非常明显的区别!请不要仅基于此进行切换。)