我正在为安装在 UR 机器人中的摄像头开发 URCap,我需要写入并读取摄像头的响应。
相机配备了对象检测算法,其工作方式是:我们向其发送一个字符串“Run.LocateAll”,它会返回检测到的对象的坐标“x,y,z,rx,ry, rz" 也是字符串格式。我可以使用 writeByte() 方法发送定位命令(我尝试使用 writeUTF(),但奇怪的是,它发送“%Run.LocateAll”,并在字符串开头带有 %,因此它不起作用)并且我知道该命令正在工作,因为相机 GUI 向我显示了找到的对象。
问题在于读取,因为当我使用 readUTF() 方法时,机器人程序冻结。我已经尝试过其他方法,例如 readLine() (它也会冻结),但没有成功。我会把我的代码和机器人程序的屏幕截图放给你看。
private static void socketCommunication(ScriptWriter writer, String ip, int port) {
try{
Socket s=new Socket(ip,port);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
dout.writeBytes("Run.LocateAll,3");
DataInputStream din = new DataInputStream(s.getInputStream());
System.out.println(din.readUTF());
din.close();
dout.flush();
dout.close();
s.close();
}
catch(Exception e){System.out.println(e);}
}
提前感谢您的帮助。
我希望我的程序可以从套接字读取并返回检测到的对象的字符串“(x,y,z,rx,ry,rz)”
A
DataInputStream
和 DataOutputStream
使用特定格式来序列化数据。如果对方不使用相同的格式,他们在读取时会得到垃圾(或者至少是以 2 字节垃圾为前缀的字符串),并且您在读取时可能会阻塞(或消耗太多数据)。
具体来说,
writeUTF()
写入一个(2字节)长度的前缀字节数组,并使用“修改的”UTF-8将字符串转换为字节。这可能就是为什么另一方得到 %
(或更可能是 \000%
),尽管这意味着字符串有 37 个字符,而不是像 "Run.LocateAll,3"
这样的 15 个字符,因为这会导致前缀为 (unprintable) \000\017
。
同样,
readUTF()
将前 2 个字节解释为长度,然后读取该长度的字节数。这意味着,如果另一方没有发送用 writeUTF()
编写的内容,它实际上可能会尝试读取太多字节并无限期地阻塞(这可以解释你提到的冻结)..
简而言之,您描述的行为表明它不使用
DataInputStream
和 DataOutputStream
的数据序列化格式,并且可能需要纯字符串(例如用 OutputStreamWriter
编写)。
您需要找到该相机实际协议的文档,并正确实现它。