Wednesday, April 22, 2009

终于搞定了 998--ERROR_NOACCESS

最近在用WINDOWS 的NAMED PIPE, 被一个问题困扰了好久. 现象是我的PIPE SERVER 不定时的会报错, READFILE 失败, 返回的错误代码是 998!
 
于是查MSDN,用VS的ERROR LOOK UP看, 发现998 的意思是INVALID ACCESS TO MEMROY LOCATION. 不过这个解释太含糊了, 为什么会INVALID呢? 为什么PIPE SERVER 时好时坏呢? 代码一直都没变啊. 没办法, 只好把PIPE CLIENT 那边的信息打印出来, 看看是不是CLIENT的问题. 检查之后发现CLIENT端正常, 是SERVER先 丁咗(死掉)的. 可是SERVER为什么有时又能正常读消息呢? 最讨厌这种时好时坏的BUG了. 如果一直不行, 我也容易查, 容易试. 但是来个段誉六脉神剑式的, 时灵时不灵, 那就头大死了.
 
接下来又把MSDN上PIPE使用的例子看了好几遍,觉得自己的代码也没什么不对的地方. 然后GOOGLE PIPE 998, 也没有找到什么有用的信息. 然后又把以前写的基本PIPE CLIENT SERVER测试的小程序拿出来, 看看是不是因为CLIENT 了先关掉, 所以SERVER读不出来了? 发现也不是.
 
气急败坏之下,有一种用MEMORY MAPPED FILE 重新写通信机制的冲动. 因为我怀疑WINDOWS PIPE是不是本身就有缺陷, 有内部BUG? 只不过一般人不知道呢? 还好脑子还没有完全坏掉, 想想PIPE 不至于这么弱, 而且我只是在本机的2个进程间通信, 没有什么特别复杂的. 如果用MMF 是效率高点,不过也更加容易出错了.
 
无奈之下, 继续GOOGLE, 这次点了下在GOOGLE GROUP了搜寻998 PIPE的连接. 你别说, 还真让我找到了一个挺有用的贴子, 如下:
http://groups.google.com/group/microsoft.public.win32.programmer.kernel/browse_thread/thread/4d4156c7d388f128/bdf7c4615bfaebdb?lnk=st&q=error+998+pipe&rnum=9&hl=en#bdf7c4615bfaebdb
这里起码解释了998的含义到底是什么, 原来是READFILE自己传进去的BUFFER有问题. 而和SECURITY 无关. 其实之前我还真往SECURITY 方向查了半天.
 
现在对998的理解又深入了一步, 那么仔细检查我的代码吧. 不看不知道, 一看吓一跳. 原来我给READFILE 传的参数还真有问题. READFILE里有2个参数,一个是BUFFER指针, 一个是BUFFER大小(有多少BYTE). 我发现, 原来我给READFILE 传了一个实际大小为1024BYTE的BUFFER, 但是告诉他BUFFER的SIZE是2048! -_-|| . 为什么开始没发现这个错误呢? 因为我把PIPE的读消息函数又包了一层, 封到一个类里去了. 所以不看类的实现是看不出来的. 或者说是函数的接口定义的不好, 容易有歧义.
 
问题找到了, 那么改起来就方便了. 2分钟改完, 赶紧测试了一下, 一切顺利, 再也没有该死的998错误了. 

No comments: