socket接包切数据时遇到的诡异问题
来源:互联网 发布:英语复读机软件 编辑:程序博客网 时间:2024/05/16 11:18
最近在写一个socket方面的小程序,遇见一个我个人觉得很诡异问题。
客户端发包我用php写的,代码很简单并且我也测试过,没有任何问题,我就不贴出来献丑了,调用接口为:
function send($socket, $data)
$data参数就是php客户端要发送给服务器的数据,这个send函数会把数据切割成一个一个的片段,并给每个片段增加协议头,然后调用socket_write发送给服务器。
服务器程序用c++写的,一个简单的测试代码,功能是:连接好socket后,先尝试接收固定长度的数据,这个数据就是协议头,从协议头中取出给定好的数据长度和数字签名,然后按照数据长度获取数据,拿到数据后再和数字签名比对看看是否合法,若合法则表明本次收包没问题,接续接受下一个包。。。。
整个流程很简单,下面我贴一下我写的c++代码:
- /**
- * receive the data from the socket
- *
- * protocol format: [flag(1) | size(4) | md5(32) | data(size) ]
- *
- * @param socket
- * @param data
- */
- int Receive(int socket, std::string *data)
- {
- while(1)
- {
- //first, get the protocol header
- int total = HEADERSIZE;
- char header[HEADERSIZE] = {'0'};
- int howMany = 0;
- while(total > 0)
- {
- howMany = read(socket, header + howMany, total);
- if(howMany < 0)
- return -1;
- total -= howMany;
- }
- //verify the flah
- if('M' != header[0])
- return -2;
- //get the data size
- char tmpLength[4];
- strncpy(tmpLength, header+1, 4);
- int length = atoi(tmpLength);
- if(length <= 0)
- return length; //if the length < 0, means something wrong happen, or if the length = 0, means the data finish.
- //get the data
- char buffer[length];
- //memset(buffer, '0', length);
- howMany = 0;
- while(length > 0)
- {
- howMany = read(socket, buffer + howMany, length);
- if(howMany < 0)
- return -1;
- length -= howMany;
- }
- //verify the data
- std::string onePart(buffer);
- MD5 md5(onePart);
- std::string verification(md5.md5());
- if(verification.compare(0, 32, header + 5, 32) != 0)
- return -3;
- //merge the part of data
- data->append(onePart);
- }
- std::cout << std::endl; //i really fucking do not know why must do this code .
- return 0;
- }
注意看send方法的倒数第二行,我不明白为什么去掉这行,这个函数就会见鬼的在第二次(第一次竟ok)被调用时,return -3(也就是说没有通过签名验证),我排查了好久,发现只有我在为debug而增加打印代码的时候才会ok,去掉所有打印代码就又出现-3。这让我有点抓狂!最后发现只要增加个std::endl,好像就没问题了,这个std::endl是有着刷新缓冲区的作用(在记忆中有看到过),谁能来给我讲讲其中奥妙呢?
由于问题太诡异,没看明白我的描述的,可以跟帖留言,我是真心求解,不是来搞笑的,谢谢~
PS:顺便问问,c++字符串截取时,有时候最后一个字符会是007F,是为啥?我有截图:
补一下我的测试环境:
centOS6.3 x86_64
- socket接包切数据时遇到的诡异问题
- IJKPlayer 遇到的诡异问题
- 使用window.close()遇到的诡异问题
- objective-c switch 遇到的诡异问题
- 今天遇到一个诡异的问题
- Hololens开发中遇到的诡异问题
- Socket编程中的一个诡异的问题
- Socket遇到的问题
- delphi6中用TFileStream进行文件读写遇到的诡异问题
- 写服务器程序,今天遇到的诡异问题
- 遇到一个诡异的regedit.exe程序问题
- ISE使用过程中遇到的一个诡异问题
- 遇到诡异的问题 stop slave 无法停止
- UITableViewCell 自动计算高度遇到的一些诡异问题
- 遇到一个诡异目前无解的系统部署问题
- eclipse导入项目时遇到诡异问题“invalid project description”
- 遇到的一个诡异bug
- 一个使用STL::string时遇到的诡异bug
- debian arm source list
- 打开windows的路由功能
- 在自己的WSASOCKET服务端/客户端中做了一个简单的解包程序处理粘包的问题
- iphone 线程总结— detachNewThreadSelector的使用
- android service 学习
- socket接包切数据时遇到的诡异问题
- TI工程师:运算放大器用作比较器,可以吗?
- linux系统的Device-mapper机制
- 不过分年宏观经济和快乐建立科技
- NSBundle 详解
- c语言double B=6所占字节数多少
- 判断非阻塞SOCKET是否已经断开的几种方法
- wordpress 插件开发1 helloword
- NSSearchPathForDirectoriesInDomains用法
发贴一下新的代码在答案里,让希望大家帮助我答疑 – kazaff 2013-03-25