最近在写一个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
发贴一下新的代码在答案里,让希望大家帮助我答疑 – kazaff 2013-03-25