C++-socket接包切数据时遇到的诡异问题

发布于 2016-11-24 11:52:09 字数 2270 浏览 1071 评论 1

最近在写一个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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

虐人心 2017-06-13 12:55:52

/**
* 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;
total = length;
while(total > 0)
{
howMany = read(socket, buffer + howMany, total);
if(howMany < 0)
return -1;

total -= howMany;
}

//verify the data
std::string onePart(buffer);
onePart = onePart.substr(0, length); //***only get the valid size of data, this is so important
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);
}

return 0;
}

这是我更正了问题中的相关代码后的一个版本,请看我问题下面的留言

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文