通过TCP填充数据
我正在开发一个客户端 - 服务器项目,并且需要实现一个逻辑,我需要通过TCP套接字连接检查是否收到最后一个数据,然后才能继续。 为了确保我收到了所有的数据,我计划在发送的最后一个数据包中加上一个标志。我在下面有两个选项,还有相关的概率。通过TCP填充数据
i。如下所示使用一个结构体,并为最后发送的数据包填充vst_pad,并在recv端检查它是否存在。在方案二的优势在于,我没有删除从实际数据中的标志将其写入到file.Just之前检查结构
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或直到遇到新行。
您是否事先知道数据的大小,是否需要实现消息标志的结束?
因为我会简化设计,所以添加一个4字节的标题(假设您不会发送每条消息超过4GB的数据),其中包含消息的预期大小。
因此,您解析出前4个字节,计算大小,然后继续调用recv,直到获得大量数据。
您需要处理recv调用从下一条消息中获取数据的情况,以及显然的错误处理。
如果实际消息包含10个零字节,则会发生如下问题:10字节小键盘解决方案没有提出什么问题 - 假设您用零填充它?你需要避开10字节的零,否则你可能会错误地截断消息。
使用固定大小的标题和已知大小的值将缓解此问题。
您可以使用用C#编写的开源网络通信库吗?如果是这样结账networkComms.net。
问题标记为C,它是一个低级别的TCP消息应用程序。 – Alan 2012-02-26 19:02:34
MarcF:谢谢你的回复。正如Alan所指出的那样,我再次在C.Thnks编码。 – user369823 2012-02-27 02:07:08
对于一条消息(数据包)首先发送一个短的(按网络顺序)的大小,然后是数据。这可以在一个write
系统调用中实现。
在接收端,只需read
短期和转换回主机顺序(这将使一个在稍后的状态下使用不同的处理器。然后,您可以read
数据的其余部分。
埃德:感谢您的答复。我已经发送了固定数量的数据,但不确定从文件中获取的数据是否具有相同的大小或小于它的大小。 fgets和send函数在其调用中具有相同数量的len。你是否建议使用像strlen这样的函数来找出要分配给短变量的实际数据长度? – user369823 2012-02-27 02:04:36
如果这是真正地由你的应用程序发送的最后一个数据在发送端使用shutdown(socket, SHUT_WR);
这将设置TCP标志,它表示发送者 - 接收者流已经结束,接收者将知道这是因为他的recv()在接收到所有内容时将返回0(就像EOF条件),接收器仍然可以发送数据,发送者可以ñ仍然听他们,但它不能发送更多使用此连接。
BatchyX。按照设计我以后会需要相同的连接。我不知道稍后会不会使用相同的连接。这取决于用户的选择。 – user369823 2012-02-27 02:05:52
在这种情况下,通常会将数据分块为块,并提供块头和尾部。标题包含块中数据的长度,所以对等方知道预期的时间 - 只需要计算rx个字节,然后检查一个有效的预告片。该块允许在两端没有大量缓冲区的情况下进行大量数据传输。
在头文件中添加一个可以识别最后一个块的“状态”字节并不麻烦。
另一种方法是打开另一个数据连接,对整个序列化进行流式处理,然后关闭这个数据连接(就像FTP一样)。
Martin:感谢您的及时答复。我可以根据Ed先生在结构中所建议的添加空格来指示数据的长度,然后在recv端循环,直到收到数据量。我会尝试首先执行相同的操作。 – user369823 2012-02-27 02:00:44
Alan:我不知道我要发送的文件的总大小,但是我发送的是固定数量的数据。也就是说,fgets会读取,直到大小指定为-1或直到遇到新行。我可以在缓冲区上使用strlen来查找实际的数据长度。 – user369823 2012-02-27 01:16:24
,当然你必须解析这4个字节,这些字节可能会在4个不同的recv呼叫中到达。 – bew 2012-02-27 16:08:12
@Alan:Thnx为答复到目前为止。我部分实现了你的建议,但我想知道我到底知道了些什么大小要放在标题中。我正在使用fgets读取文件中的数据,并传输相同数量的大小。但是作为它的TCP,我不确定发送数据的大小,直到检查发送呼叫的返回值为止。我有点困惑于此。一个伪代码将是非常有用的... – user369823 2012-06-03 03:10:00