首先,这是我的第一个Android / Java套接字项目!看看下面的方法。我的目标是从套接字连接接收多行文本(实际上是包装器中的xml)。我试图读取每一行并将其连接到一个字符串,并将其传递回messageReceived方法进行进一步处理。读取和连接工作正常但是代码永远不会执行超出s = mBufferIn.readLine()while循环?如果我在条件测试mServerMessage的值上设置断点,它永远不会得到这么远,即使mServerMessage包含从服务器发送的所有内容。如果我删除while循环并将mServerMessage的值设置为mBufferIn.readLine()的值,则每行都会成功发送到UI线程,但我需要将整个数据包立即发送到messageReceived方法。我该怎么做才能纠正这个问题?
更新
我已经修改了run()方法中的while循环,以根据下面的建议检查消息的结尾。这是正常工作,因为在消息中找到ETX字符时连接停止,但IF条件永远不会执行。这可能与AsyncTask有关吗?我已经发布了位于MainActivity任务中的ConnectTask类,因为这是我连接到套接字的方式。
MainActivity
public class ConnectTask extends AsyncTask<String, String, TcpClient> {
@Override
protected TcpClient doInBackground(String... message) {
mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
@Override
//implement the messageReceived method
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//do something with received message
}
}
TcpClient类
public void run() {
mRun = true;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("TCP Client", "C: Connecting...");
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
mBufferOut = socket.getOutputStream();
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (mRun) {
String s;
while ((s = mBufferIn.readLine()) != null && s.indexOf(ETX) < 0) {
mServerMessage += s;
}
if (mServerMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
答案 0 :(得分:1)
您正在设置一个循环,其中停止条件是.readLine()
为null
。这显然不会发生,因为每次从远程服务器读取一行时,它都有一些内容(与null
不同),所以你不会离开循环。
有几种方法可以达到你想要的效果:
其中一个将从远程服务器发送“EOF”消息(如果可以的话),例如,发送String
这将是“嘿,我已经完成了,现在你必须停止“。然后将循环更改为:
while (!(s = mBufferIn.readLine().equals("Hey, I'm done and now you have to stop"))) { ... }
另一个是按原样离开循环而不是在每一行上追加读取的内容,而是调用一个方法(比如processString(s)
),这将启动Thread
并发送主要Activity
的内容。因此对Intent
,BroadcastReceiver
等有效。这样你就不会阻止循环的其余部分的执行并按原样处理字符串。