C Socket,在数据流之前添加标头

时间:2014-10-02 03:24:51

标签: c sockets

我通过套接字发送字节,工作正常。现在就传输文件而言,我需要在发送实际数据之前发送文件大小。所以我提出了一个想法,即在文件数据之前将文件大小作为标题发送。

例如,如果文件数据是"1234",那么socket将在"1234"之前发送4个字节的长度(即4),并且将通过套接字发送8个字节。前4个字节包含数据长度,其余字节是实际数据。

我可以通过以下方法将int转换为字节(即char数组):

bytes[0] = (n >> 24) & 0xFF;
bytes[1] = (n >> 16) & 0xFF;
bytes[2] = (n >> 8) & 0xFF;
bytes[3] = n & 0xFF;

问题是我无法在实际数据之前添加这4个字节:

char *data = [Actual data of file];
char *buffer = malloc(4 + strlen(data));
strcpy(buffer, bytes);
strcat(buffer, data);

结果是bytes[]消失,bufferdata具有完全相同的数据

任何人都可以帮我吗?

2 个答案:

答案 0 :(得分:1)

好的,我假设你知道你在做什么数据,并且它是一个以空字符结尾的字符串,并且你不想发送终结符(因为你没有为它分配空间)在你的缓冲区)。你想要的可以做如下:

size_t len = strlen(data);
char *buffer = malloc(4 + len);
memcpy(buffer, bytes, 4);
memcpy(buffer + 4, data, len);

请注意,您的字节不是字符串,因此您不希望对它们使用strcpystrcat等字符串函数。 memcpy(dst, src, len)只是将len字节从src精确复制到dst,而不关心实际内容,例如nul-terminators。

答案 1 :(得分:1)

您不需要将长度字节前置到数据缓冲区。使用单独的缓冲区。然后,在send()数据缓冲区之前,您可以send()长度缓冲区。更好的是,您可以将数据长度存储在32位intuint32_t中,使用htonl()按网络字节顺序排列字节,然后直接send()不将其复制到自己的缓冲区。如果将发送逻辑包装在一个函数中,这将变得更容易管理,例如:

void sendData(void *data, uint32_t datalen)
{
    uint32_t len = htonl(datalen);
    send(socket, &len, sizeof(len), 0);
    send(socket, data, datalen, 0);
}

char *data = [Actual data of file];
uint32_t datalen = [Actual length of file];

sendData(data, datalen);