通过TCP填充数据

时间:2012-02-26 18:54:33

标签: c networking tcp padding

我正在开发一个客户端 - 服务器项目,需要实现一个逻辑,我需要在继续之前检查是否通过TCP套接字连接收到了最后一个数据。 为了确保我已收到所有数据,我打算在发送的最后一个数据包上填写一个标志。我有两个选项,如下所示,还有相关的概率。

我。使用如下结构并填充vst_pad以获取最后发送的数据包,并在recv端检查其是否存在。优于选项2的优点是,在将其写入文件之前,我不必从实际数据中删除该标志。只需检查结构的第一个成员

typedef struct
   {
    /* String holding padding for last packet when socket is changed */
    char vst_pad[10];
    /* Pointer to data being transmitted */
    char *vst_data;
    //unsigned char vst_data[1];
   } st_packetData;

问题是我必须在每次发送调用时序列化结构。此外,我不确定是否将在一次recv调用中通过TCP接收整个结构,因此必须添加逻辑/开销以每次检查这一点。到目前为止,我已经实现了这一点,但后来发现基于流的TCP可能无法保证在一次调用中恢复整个结构。

II。使用类似strncat的函数将结尾的标志添加到最后发送的数据中。

问题是我必须使用正则表达式函数或strstr函数检查每个接收调用是否存在该标志,如果必须,则必须从数据中删除它。

此应用程序将用于大型数据传输,因此希望在每次发送/接收/读/写调用时增加最小的开销。非常感谢知道是否有更好的选择,然后上面两个或任何其他选项来检查最后一个数据包的接收。该程序是多线程的。

编辑:我不知道我要发送的文件总大小,但是我发送了固定数量的数据。这是fgets读取,直到指定大小-1或直到遇到新行。

5 个答案:

答案 0 :(得分:2)

您是否事先知道数据的大小,是否要求您实现消息结束标志?

因为我会简化设计,所以添加一个4字节的标头(假设你没有为每条消息发送超过4GB的数据),它包含了预期的消息大小。

因此,您解析前4个字节,计算大小,然后继续调用recv,直到获得那么多数据。

你需要处理你的recv调用从下一条消息中获取数据的情况,以及明显的错误处理。

如果实际消息包含10个零字节,假设您用零填充它,那么10byte pad解决方案没有提出的另一个问题是什么?你需要逃避10字节的零,否则你可能会错误地截断消息。

使用固定大小的标头和已知的大小值可以缓解此问题。

答案 1 :(得分:1)

对于消息(数据包),首先发送大小的短(网络顺序),然​​后发送数据。这可以通过一次write系统调用来实现。

在接收端,只需read短路并转换回主机顺序(这将使人们可以在以后使用不同的处理器。然后您可以read其余数据。

答案 2 :(得分:1)

在这种情况下,通常会将数据阻塞为块并提供块头和预告片。标头包含块中数据的长度,因此对等体知道预期何时播放 - 它所要做的就是计算rx字节,然后检查有效的预告片。这些块允许大数据传输,两端都没有大量缓冲区。

在标题中添加一个可识别最后一个块的'status'字节并不是一件容易的事。

另一种方法是打开另一个数据连接,流式传输整个序列化,然后关闭此数据连接(就像FTP一样)。

答案 3 :(得分:0)

您能否使用用C#编写的开源网络通信库?如果是,请结帐networkComms.net

答案 4 :(得分:0)

如果这确实是您的应用程序发送的最后一个数据,请在发件人方使用shutdown(socket, SHUT_WR);

这将设置FIN TCP标志,表示发送方 - >接收方流已结束。接收器将知道这一点,因为他的recv()将在收到所有内容时返回0(就像EOF条件一样)。接收方仍然可以在之后发送数据,发送方仍然可以监听它们,但是使用此连接无法发送更多数据。