以下while循环有什么问题?

时间:2017-10-21 07:59:14

标签: c sockets while-loop winsock strtok

我有一个 c winsock 代码部分,其中客户端收到逗号分隔的文件指纹流,如下所示。我需要在while循环中使用strtok_s()从流中提取指纹。我的问题是大部分时间客户端无法提取从服务器发送的确切指纹数,即使收到的数据(通过调试观察)正是服务器发送的数据。 我在这里缺少什么?

recv_size = recv(clnt_sock, fp_buf, BUF_LEN, 0);
            received_fp_size += recv_size;
        if (0 != (last_string_len = recv_size % 33))
            strncpy(last_string, &fp_buf[(recv_size - last_string_len)], last_string_len);//
        while (recv_size > 0)
        {
            unique_fp = strtok_s(fp_buf, ",", &strtk);
        k:
            while (unique_fp != NULL)
            {
                memcpy(unique_fp_buf[unique_files_count], unique_fp, 32);
                unique_fp = strtok_s(NULL, ",", &strtk);
                unique_files_count++;

            }


            recv_size = recv(clnt_sock, fp_buf, BUF_LEN, 0);
            received_fp_size += recv_size;
            if (last_string_len > 0)
            {
                unique_fp = strtok_s(fp_buf, ",", &strtk);
                strncat_s(last_string, unique_fp, strlen(unique_fp));
                memcpy(unique_fp, last_string, 32);
                last_string_len = 0;
                goto k;
            }

        }

if (0 != (last_string_len = recv_size % 33))行背后的原因是;服务器发送多个33字节的字符串(32表示指纹,1表示昏迷demlimiter)

1 个答案:

答案 0 :(得分:1)

一个问题是,您永远不会检查fp_buf实际上是否包含完整的令牌。例如,如果第一个调用仅接收20个字节,则复制部分指纹将导致代码失败。

我认为另一个问题在于:

memcpy(unique_fp, last_string, 32);

似乎您正在复制到接收缓冲区,因此会覆盖您尚未处理的一些数据。此外,您可以覆盖令牌。

也许你真的想要:

memcpy(unique_fp_buf[unique_files_count], last_string, 32);
                                          ^^^^^^^^^^^
unique_fp = strtok_s(NULL, ",", &strtk);
unique_files_count++;

除此之外,我认为你使代码比需要的复杂得多。使用goto类型告诉您设计是错误的。

您可以这样做,而不是使用last_string

1) Call recv
2) Process all complete fingerprints
3) Copy the remainder (i.e. the last partial fingerprint) to the start of `fp_buf`
4) Call `recv` with an offset into `fp_buf`
5) Repeat from step 2 (i.e. use a while loop - don't use goto

第3步可能是这样的:

recv_size = recv(clnt_sock, fp_buf + length_of_remainder , BUF_LEN -  length_of_remainder, 0);

通过这种方式,您无需处理last_string内容