【发布时间】:2015-03-25 16:34:01
【问题描述】:
我正在开发一个 Android 应用程序,
- 首先,我必须通过 TCP 套接字连接到硬件服务器
- 连接后,我必须向服务器发送*99*1##,然后服务器将响应“*#*1##*#*1##”
- 然后,我需要保持此套接字处于活动状态并读取传入消息
- 此后,服务器可以不时向我发送消息。但是,消息何时发送或消息长度未确定。
- 每条消息都以“##”结尾,例如,*1*1*18##、*1*0*19##、*1*1*#4*11## 等。李>
- 当客户端(此应用)收到消息时,它会通知 Activity 更新 UI。
所以,我创建了一个线程子类来做到这一点
public class ServerThread extends Thread {
public interface OnReadListener {
public void onRead(ServerThread serverThread, String response);
}
Socket socket;
String address;
int port;
OnReadListener listener = null;
public ServerThread(String address, int port) {
this.address = address;
this.port = port;
}
@Override
public void run() {
try {
socket = new Socket(InetAddress.getByName(address), port);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
PrintWriter writer = new PrintWriter(bw, true);
writer.println("*99*1##");
writer.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while (!socket.isConnected() && !Thread.currentThread().isInterrupted()) {
line = br.readLine();
if (line != null) {
Log.i("Dev", "Line ")
if (listener != null) {
listener.onRead(this, line);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setListener(OnReadListener listener) {
this.listener = listener;
}
}
而在活动中,我是这样做的
public class MainActivity extends Activity {
ServerThread st = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
@Override
public void onResume() {
startMonitoring();
super.onResume();
}
@Override
public void onPause() {
stopMonitoring();
super.onPause();
}
private void startMonitoring() {
stopMonitoring();
st = new ServerThread(SERVER_IP_ADDRESS, SERVER_PORT);
st.setListener(new OnReadListener{
@Override
public void onRead(ServerThread serverThread, String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI or do something with response
}
})
}
});
st.start();
}
private void stopMonitoring() {
if (st != null) {
st.stop();
st = null;
}
}
}
在我开始这个活动后,我发现
- 消息“*99*1##”已发送到服务器,我可以从服务器硬件中看到此消息。
- 但是,我只收到来自服务器 '*#*1##*#*1##' 的第一行响应
- 之后,套接字仍然连接(未打印堆栈跟踪),但我再也没有收到来自服务器的任何进一步消息。侦听器永远不会被调用。
我不知道如何使这项工作。欢迎任何建议。
您可能需要知道的一些注意事项
我不确定 BufferReader 是否是我工作所需的正确对象。因为当它读取失败时,它将返回 null 并且循环将继续运行。我可能需要一些可以冻结等待输入的线程的对象。该对象可以等待输入,因为服务器可能会在几秒钟、几分钟、几小时或更长时间内发送消息。收到消息后,继续执行代码并进入下一轮循环。
(我是全职 iOS Dev,对 Java 不是很熟悉)
最终编辑
我仔细检查代码后发现我犯的愚蠢错误
writer.println("*99*1##")
基本上,println 会发送“*99*1##”,然后跟着 newline。但是我的硬件服务器不喜欢这样,所以它终止了连接。这就是为什么我从 BufferReader 的 readLine() 中得到 null 的原因。
我改成之后
writer.print("*99*1##")
服务器收到“*99*1##”并保持连接。然后,我可以像 EJP 再次建议的那样循环读取响应
String line;
while ((line = br.readLine()) != null) {
if (listener != null) {
listener.onRead(this, line);
}
}
if (listener != null) {
listener.onTerminated(this);
}
【问题讨论】:
标签: java android multithreading sockets tcp