C中从套接字阅读大量数据

qojgxg4l  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(84)

我有一个python tcp服务器,它接受连接并生成一个长度在(0,1M)字符之间的随机字符串,另一方面,我有一个c客户端,它需要监听该套接字并读取字符串,并将其转换为与服务器返回的字符串长度相同的单个字符。

int receiver(int soc_desc, char * buffer)
{
    char *arr = (char *)malloc(sizeof(char));
    unsigned int received , total_received;
    while (1)
    {
        memset(arr, 0, MAX); // clear the buffer
        if ( received = recv(soc_desc, arr , MAX, 0) < 0)
        {
            break;
        }
        else
        {
            total_received += received;
        }
    }
    printf("%s\n",arr);
    return received; 
}
// soc_desc is the socket descriptor 
// buffer is the buffer that will hold the final output

我能想到的唯一方法是使用malloc来读取从服务器返回的数据块,但我在尝试解决这个问题时遇到了困难,当客户端完成从服务器接收数据时,我需要将char指针数组转换为单个字符

e1xvtsh3

e1xvtsh31#

我找到了一种方法来做到这一点,但这是没有足够的测试,肯定会导致内存问题

char *arr = malloc(sizeof(char));
    char tmp_buff[MAX];
    memset(arr,0,MAX);
    while (recv(soc_desc, tmp_buff , MAX, 0) > 0 )
    {
        strcat(arr , tmp_buff);
        printf("Size : %ld  arr : %s\n",strlen(tmp_buff),tmp_buff);
    }
92vpleto

92vpleto2#

重组网络数据,特别是来自TCP的数据,可能会变得很棘手。下面的代码是未经测试的,当然不能解释所有的意外情况,但希望是沿着正确的道路,你需要做的。

ssize_t receiver(int soc_desc, char * buffer)
{
    // Whats the buffer argument used for?
    // what you had before only allocated space for 1 char. That's not what you want
    // This allocates for MAX+1 chars (I'm doing +1 for a NUL terminator)
    char *arr = malloc(MAX+1);
    // if MAX is small enough, you could do
    // char arr[MAX+1];

    // 0 buffer. You could use calloc instead of malloc + memset
    memset(arr, 0, MAX+1);
    // initialize total_received to 0
    ssize_t received , total_received = 0;
    size_t spaceLeftInBuf = MAX;
    while (1)
    {
        // don't memset here, you'll erase the data you received last iteration

        // write data to arr+total_receieved. This way you won't overwrite what
        // you received the last iteration
        received = recv(soc_desc, arr+total_received, spaceLeftInBuf, 0);
        if (received < 0)
        {
            // there was an error
            perror("recv failed: ");
            // do something with the data already received? Ok, break and
            // print what we've got
            break;
        }
        else if (received == 0)
        {
            // socket closed gracefully, suppose we can break again and print
            // what we've got
            break;
        }
        else
        {
            // update counters
            total_received += received;
            spaceLeftInBuf -= received;
            // is our buffer full? This may not be the right check, you need to
            // decide when to process the data
            // total_received better not ever be > MAX...
            if (total_received >= MAX)
            {
                // "process" the data by printing it
                printf("%s\n", arr);
                
                // reset
                total_received = 0;
                spaceLeftInBuf = MAX;
                // not particularly necessary to reset this to all 0s, but should
                // make sure printing goes smoothly if we break out of this loop
                memset(arr, 0, MAX);  // arr[MAX] should already be '\0' from above
            }
            
        }
    }
    printf("%s\n",arr);
    free(arr);
    return received; 
}

参见Do I cast the result of malloc?

相关问题