socket接包切数据时遇到的诡异问题-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

2016-06-03 19:12:03 1802 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;
}

注意看send方法的倒数第二行,我不明白为什么去掉这行,这个函数就会见鬼的在第二次(第一次竟ok)被调用时,return -3(也就是说没有通过签名验证),我排查了好久,发现只有我在为debug而增加打印代码的时候才会ok,去掉所有打印代码就又出现-3。这让我有点抓狂!最后发现只要增加个std::endl,好像就没问题了,这个std::endl是有着刷新缓冲区的作用(在记忆中有看到过),谁能来给我讲讲其中奥妙呢?

取消 提交回答
全部回答(1)
  • a123456678
    2019-07-17 19:27:08

    你这边的read写的有点问题
    howMany = read(socket, header + howMany, total);
    假如第一次没读全数据,howMany大小为第一次读取的数据长度
    第二次读取时buffer的位置就变成了header指针+第一次读取的长度,同时howMany是第二次读取的长度。这里还没有问题。
    假如还有第三次读取就会有问题,buffer的位置变成了header+第二次读取长度。正确的位置应该是header+第一次读取长度+第二次读取长度。

    最后字符串截取的问题怀疑是传入字符串的时候长度没控制好。把结束符和结束符后面一个字符也给传过去了。

    另外memset的时候一般都设置成0,而不是'0'。后面一个是字符0,实际的值是0x30

    0 0
相关问答

0

回答

通过Flink 监听Socket的数据

2021-11-30 18:01:36 186浏览量 回答数 0

1

回答

socket中流套接字与原始套接字有什么区别?

2021-11-06 17:50:52 110浏览量 回答数 1

2

回答

Dubbo3.0 在阿里双十一考拉大规模落地的背景是怎样的?

2021-03-17 17:18:47 857浏览量 回答数 2

1

回答

关于socket通信接受byte数组问题:报错

2020-06-06 23:40:54 400浏览量 回答数 1

0

回答

对接阿里的Rocket ,http协议的sdk出现的问题

2020-03-03 18:08:53 592浏览量 回答数 0

1

回答

SOCKET连接延迟,初始连接后可以正常收、发数据。经常过几秒、几分钟后就无法通信。再几分钟又可以了

2019-03-18 08:22:35 830浏览量 回答数 1

1

回答

sql数据库文件 导入到DMS的数据库里 导入中间出错

2018-02-08 14:13:17 1053浏览量 回答数 1

1

回答

手机端用socket通信接收服务器端的发送的数据,利用handler更新在界面,但现在显示不了数据,不知道代码哪里出问题了。

2016-06-02 09:29:30 2648浏览量 回答数 1

6

回答

c语言socket通信时可以发送json格式的数据吗

2016-05-30 17:44:12 7549浏览量 回答数 6

1

回答

php 如何开启 sockets

2015-12-22 20:16:41 2726浏览量 回答数 1
+关注
文章
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载