代码作者当时的建议是每个标签做成函数。整个代码都是基于非阻塞的,再加上C_STOP处理起来比较麻烦,作者是说获取输入重复计算接收长度,反正没收到数据,再算一次无所谓,这里最好加上sleep函数让出cpu
改掉goto是件小事,暂且不提。不妨先探讨一下原代码的正确性和存在的隐患。
一开头除去变量的初始,直接就goto lab_skip_get_header。也就是说在调用mysh_recv_data前已经接收过C_DATAB了。由于你只展示了这么一个函数,其外的操作我无从得知,关于这点你能确定就好。
在lab_skip_get_header部分,通过recv不断接收数据。问题来了。
从recv的调用方式推测它从数据源中读取不超过缓存need数量的数据到p,并返回实际读取的数据长度。当读取不成功时则返回0。
进一步推测recv(p, 0)必然返回0。
由于recv是以函数指针的方式传入mysh_recv_data的,所以推测这么做的原因是你的数据源不止一个,根据不同的源采用不同的读取方式。这类似C++中的多态思想。
由于数据长度是不定的,你确定MYSH_EN_DATA_BLOCK_SIZE的尺寸足够用么?
一旦数据达到或超过MYSH_EN_DATA_BLOCK_SIZE,lab_skip_get_header部分中need将等于0,并由recv(p, 0)返回0,将导致这段代码陷入死循环。
以上问题的防范措施在mysh_recv_data外有么?通过协议避免的?
同样,在lab_try_find_data_end部分中c = *p一语的位置也存在风险。它可能读取EN_DATA_BLOCK外的字段而导致内存访问错误使程序崩溃。单这一句的问题可以通过调换和它下一句的顺序来避免。
再说说读到数据后的处理过程。你在3楼的解释中说到转出来的本地数据有误也会重新接收。但lab_finded_data部分的代码中我没看到相关逻辑。
mysh_data_decode即是解码函数对吧,解码成功则返回解码后的数据长度,否则返回0是吧?
这里你只对加密数据的长度做了判断,解码后不管结果对错直接发送C_OK指令后退出了mysh_recv_data。
当然,对解码后数据的判断可以在mysh_recv_data外做(通过size可以判断),也希望你们是这么做的。
lab_finded_data部分中if (n < 1) continue这句的位置也很混乱。它应该放在解码函数调用之前。如果原数据本就是错的还解它干什么?
以上分析仅供参考。还是那句话,你只展示了这一个函数的代码,它之外你们做了什么我不得而知,无法全面评估你们代码中的漏洞。相比之下去掉goto则是小事一桩。