我希望能够异步等待套接字,然后同步读取它:
for (;;)
{
while (data available on socket)
{
read message from socket;
process it;
}
do something else;
}
我需要这个,因为我想同时使用来自GUI的消息轮询队列,所以“做其他事情”部分有一个简短的wait()
。
Java套接字可以实现吗?我尝试检查与套接字关联的.available()
上的DataInputStream
,但
我尝试使用Selector,但它要求套接字通道始终处于非阻塞模式。
答案 0 :(得分:5)
答案 1 :(得分:2)
为什么不使用两个线程(或者我误解了你想做什么)?
答案 2 :(得分:2)
来自Socket的InputStream的'available()'方法将告诉您在调用阻塞的read()方法之前套接字上是否有可用的数据。
InputStream sockIS = sock.getInputStream();
int ba; // Number of bytes available to read from socket
for (;;) {
while ((ba = sockIS.available()) > 0) {
read message from socket;
process it;
}
do something else;
}
如果没有要读取的数据,请不要调用阻塞读取。不要阻止阅读比当时更多的数据。
感兴趣的相关方法(但不是针对您的特定需求)是sock.setSoTimeout(millis)此调用允许您调用sock.read(...)并让它等待最多一段特定的时间在它抛出异常(您将处理)或返回数据之前。如果您希望获得快速响应但希望处理服务器可能不再响应的问题,这将非常有用。
另一个问题是你把一个大括号放在错误的行上,当每个人都知道它们属于if / while / for语句的末尾时: - )
答案 3 :(得分:0)
在套接字编程中,数据可以作为任意块进入,具体取决于发送系统,中间链接以及操作系统如何处理PSH标记之间的交互。您需要在中间放置一个BufferedInputStream并使用available()方法并推回字节,直到您有一个完整的“消息”,然后您可以处理它。
正确的java解决方案包括创建自己的MessageInputStream,它包装BufferedInputStream并提供类似的available()功能,告诉调用者有多少消息可以立即读取。
答案 4 :(得分:0)
我会做
public class MainClass extends WhateverSuperClass implements WhateverInterface { // . . . private Listener listener; public MainClass() { listener = new Listener(this); } public void theMethod(){ //do something else } } public class Listener extends Thread { public Listener(MainClass clazz) { // initialize thread resources (sockets, database connections, etc) start(); Thread.yield(); } public void run() { for (;;) { // there's no need to test if there is // data available on socket, since this // loop runs in a separate thread // read message from socket; // clazz.process(message); } } }