我正在尝试从 msn 总机套接字读取文本
public String readStream() {
String temp = null;
try {
temp = buffReader.readLine();
System.out.println("<<< " + temp);
} catch (Exception e) {
e.printStackTrace();
}
return temp;
}
// this method is called
public void print() {
while (socket.isConnected()) {
readStream();
}
}
在 msn 上收到消息时,输出应该是这样的(根据太 http://www.hypothetic.org/docs/msn/switchboard/example_session.php)
<<< MSG bob@passport.com Bob 143rn
MIME-Version: 1.0rn
Content-Type: text/plain; charset=UTF-8rn
X-MMS-IM-Format: FN=Lucida%20Sans%20Unicode; EF=B; CO=ff0000; CS=0; PF=22rn
rn
Hello.
我的输出:
<<< MSG myemail@email.com MYNAME 128
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<<
如您所见,在该人发送另一条消息之前,我没有收到发送的消息。
输出:
<<< MSG myemail@email.com MYNAME 128
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<<
<<< helloMSG myemail@email.com MYNAME 127
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<<
那么如何解决这个问题,以便我可以阅读整个消息呢?
问题是流在 Hello 之后没有换行符。 因此,readLine 不会检测到行的末尾,直到下一条消息的第一行末尾的行尾。 您需要依靠消息的长度来读取预定义的字节数,以便获取整个消息。 查看此站点以获取一些提示: http://www.hypothetic.org/docs/msn/resources/faq.php#howtoparse
编辑:要实现的逻辑引用自上述网站 最相关的部分接近尾声:
每当来自服务器的新数据通过套接字到达时,请将其附加到将用作"缓存"的字符串中。每次接收数据时,也调用缓存分析器函数。
缓存解析器函数将检查缓存变量并查找换行符。
如果未找到,该函数将返回而不执行任何操作。
如果找到一个,它将读取从缓存开头到换行符的所有内容,并将其放入新变量中。然后,它将从缓存的开头删除命令,直到(并包括)换行符。
缓存解析器将查看命令的前三个字节。
如果该命令被识别为常规命令,它将调用该命令的处理程序并循环查看缓存中是否有更多命令。
这是最相关的部分
如果该命令被识别为有效负载命令,它将查看有效负载的指定长度,并将其与缓存的长度进行比较。
如果看起来整个有效负载都在缓存中,缓存解析器将取出缓存的开头,直到指定的长度,并将其存储到有效负载变量中。然后,它将为 payload 函数调用相应的处理程序,并循环回以查看缓存中是否有更多命令。
如果缓存的长度小于有效负载的指定长度,则缓存解析器会将命令添加回缓存的开头并返回。