【发布时间】:2013-06-17 11:00:22
【问题描述】:
我在与我的主应用程序不同的线程中写信给ServerSocket:
BlockingQueue<String> queue = new Queue<>();
// THREAD
ServerSocket server = new ServerSocket(2222);
Socket socket = server.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
while (true) {
String line = queue.take();
if (line != null) {
try {
logger.debug("Sending command " + line);
writer.write(line + "\n");
writer.flush();
} catch (IOException e) {
logger.error("IO error", e);
e.printStackTrace();
}
}
}
queue 从外部填充的位置。
发送内容正常,我可以通过在端口 2222 上使用 telnet 并读取调试记录器输出来验证这一点。
在 android 上,我通过以下代码在端口 2222 上读取数据:
Socket s = new Socket("host",2222);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream(),"UTF-8"));
while((line = reader.readLine()) != null) {
Log.d("PAINT","RECEIVED::" + line);
// create Message, Bundle, send Message to handler.
}
但是,我发送的每几条消息中就有一条(例如十分之一)没有被安卓手机接收。有关如何发生这种情况以及如何解决此问题的任何提示?
【问题讨论】:
-
您知道
Queue<T>不是线程安全的吗?您似乎在使用它,就好像您期望的那样。 -
好点,但似乎我们应该解决这个问题,但这不是问题;每次 Android 线程不注册读取时,我都会记录写入。
-
使用
java.util.concurrent中的集合之一。如果您要使用BlockingQueue之类的LinkedBlockingQueue,那么您可以删除您似乎正在使用的可怕的忙等待反模式。 -
另请注意,您在每个平台上都使用默认字符编码,这绝不是一个好主意。
-
作为调试的线索,您可以在发送的每条消息中添加一个计数器,以便确定缺少什么。例如:counter++; writer.write(String.format("%3d: %s\n", counter, line)); writer.flush();有了这个,您可能会知道真正丢失了什么。
标签: java android sockets java-io