【发布时间】:2015-04-18 18:40:03
【问题描述】:
更新 #2:BLUF:我想我找到了问题,但我需要帮助找出如何解决它。该设备需要一个带有前缀和后缀 STX>command ETX> 的命令(我必须删除左括号,以便 stackoverflow 会显示它)。当我使用 Hercules(有效)通过 TCP 发送时,主机正确解释 STX> 和 ETX> 并且只显示“命令”,但是我编写了一个 java 客户端程序发送相同的信息,但它在主机上显示为“STX >commandETX>”。 java有什么不同?
原文:
过去几天我一直在解决这个问题,但我没有想法,所以我在这里。首先是一些可能相关或不相关的背景信息:
我有一个 SICK LMS151 LIDAR 传感器,我需要通过 Android 应用程序访问它。传感器设计为 TCP 服务器,因此您可以作为客户端连接并发送命令 STX>sRN LMDscandataETX>。这会提示传感器将一堆数据返回给客户端。在计算机上,我可以在 TCP 客户端模式下使用 Hercules 之类的程序,发送命令并立即接收数据而不会出现问题。然而,让 Android 应用程序做同样的事情是有问题的(我在下面附上了客户端代码)。
我在一个单独的 android 设备上编写了一个服务器应用程序,我的客户端应用程序已经能够连接到该设备并交换数据。我通过连接发送命令“STX>sRN LMDscandataETX>”,这正是它在服务器端的显示方式。当服务器应用程序发送数据时,我可以在我的客户端上看到它。但是,当我尝试使用客户端连接到传感器时,它会连接但不响应我的数据请求。任何要研究的问题的想法都会有所帮助,因为在这一点上我很新鲜。谢谢!
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class TcpClient extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
runTcpClient();
}
private static final int TCP_SERVER_PORT = 2111;
private void runTcpClient() {
try {
Socket s = new Socket("192.168.0.105", TCP_SERVER_PORT);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
Log.i("TcpClient", "Connected!");
//send output msg
String outMsg = "<STX>sRN LMDscandata<ETX>";
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
//accept server response
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
//close connection
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
更新:今天在这方面花了更多时间。从 Apache 添加了一个 BoundedInputStream,希望我可能什么也没看到,因为传感器在每次读取结束时没有发送 /n 字符。也从 BufferedReader 转换为 Scanner。没有运气。我现在相当确信这不是我的客户端读取的问题,而是它以某种方式发送命令与计算机不同,因此传感器无法理解它。
【问题讨论】:
-
我将建议在命令端缺少换行符作为嫌疑人,但也许您已经检查过了。你能在某个地方(也许在路由器上?)设置一个数据包扫描器来查看所有进出传感器的流量吗?看起来该仪器正在通过 TCP 代理一些较旧的串行协议,因此它的网络实现也有可能是相当“简单”的东西,作为事后的想法被移植到早期的设计中(即,错误或挑剔的细节它应该不是)。你能通过 Android 设备上的 connectbot 之类的工具与它交谈吗?
-
感谢您的回复!老实说,我不确定如何在路由器上设置数据包扫描器,但我认为传感器最初设计为串行设备是对的。我下载了 Connectbot,它似乎可以连接,但我不知道如何在应用程序中输入数据。相反,我下载了另一个名为 TCP Client 的应用程序。它连接并且我可以发送数据,但传感器也不会响应它。通过测试的一个观察结果可能有用:我编写的 tcp 服务器会立即响应我的 java tcp 程序,但会挂断直到与 Hercules 断开连接......很奇怪。
标签: java android sockets tcp tcpclient