前两天同事在使用boost的read_util库的时候遇到一个很诡异的问题,如果用read_util("</data>")这样的调用,第一个请求可以得到,但是第二个请求会卡住,永远也拿不到。从服务器端看到的情况是,第二个响应已经完整的发送出去,但是read_util就是不返回。比较奇怪的是如果用read_util('>')这样调用,那是没有任何问题的。难道这个是read_util的bug?
首先我们要相信一个道理“问题越诡异,造成问题的原因越sb”。最终查找了半天才发现这个问题的根本所在。其实这就是一个在文本协议中使用了/0所造成的问题。read_util(string)这样的函数,它所用的肯定是string.find这样的函数,而这样的函数它是用字符串查找的,这表示它一旦遇到/0就不再往后查找了。
那么我们再来看看上面描述的那个问题,那个问题的关键在于每个响应最后会有一个/0字符。因此在第一个包读完之后,接下来读到的第一个字符就是/0,那么第二个包读的时候,不论读到多少数据,这个字符串的内容是/0xxxxxxxx,在这个一个长度为0的字符串上进行查找"</data>",必然找不到任何有用的信息。
结论:在处理网络流的时候,即使协议是文本协议,最好还是把它当作二进制来处理,或者用一些自己写的字符串匹配函数,否则可能会被/0给搞死。