3

我编写了一个简单的服务器和客户端应用程序,可以在 TCP、DCCP 和 UDP 协议之间切换。目标是将文件从一个文件传输到另一个文件并测量每个协议的流量,因此我可以针对不同的网络设置比较它们(我大致知道结果应该是什么,但我需要准确的数字/图表)。无论如何,在不同的计算机上启动这两个应用程序并启动 tcpdump 后,我只能从 4GB 文件中获取 tcpdump-log 的前几 MB(~50MB)。这些应用程序是用标准的 C/C++ 代码编写的,可以在网络上的任何地方找到。可能是什么问题或我在这里做错了什么?

--编辑

我使用的命令行是:

tcpdump -s 1500 -w mylog

tcpdump仅在前 ~55 秒内捕获数据包。那是客户端需要将文件发送到套接字的时间。之后它停止,即使服务器继续接收文件并将其写入硬盘驱动器。

--编辑2

源代码

client.cpp
server.cpp
common.hpp
common.cpp

--编辑最终

正如你们中的许多人所指出的(正如我所怀疑的),源代码中有几个误解/错误。在我清理它(或几乎重写它)之后,它可以根据需要与 tcpdump 一起使用。我会接受@Laurent Parenteau 的回答,但仅限于第 5 点。因为它与问题唯一相关。如果有人对正确的代码感兴趣,这里是:

源代码编辑

client.cpp
server.cpp
common.hpp
common.cpp

4

5 回答 5

7

代码中有很多错误。

  1. 文件大小/传输大小硬编码为 4294967295 字节。所以,如果提供的文件不是那么多字节,你就会遇到问题。
  2. 在发件人中,您没有检查文件读取是否成功。因此,如果文件小于 4294967295 字节,您将不会知道它并通过网络发送垃圾数​​据(或根本没有)。
  3. 当您使用 UDP 和 DDCP 时,无法保证数据包的顺序,因此接收到的数据可能是无序的(即垃圾)。
  4. 使用 UDP 时,不会重传丢失的数据包,因此可能永远无法接收到某些数据。
  5. 在接收器中,您不会检查收到了多少字节,您总是将 MAX_LINE 字节写入文件。因此,即使您收到 0 个字节,您仍然会写入文件,这是错误的。
  6. 当您使用 UDP 时,由于您在大腿循环中发送,即使 write() 调用返回的发送字节数与您请求的相同,网络堆栈或网络接口也可能会丢弃大量数据,因为没有适当的拥塞控制。因此,您需要自己进行一些拥塞控制。

这只是快速扫描代码,可能还有更多问题......

我的建议是:尝试使用 TCP 传输,对您读取/发送的文件执行 md5sum,对您接收/保存的文件执行 md5sum,然后比较 2 个 md5sum。一旦你有这个案例工作,你可以开始使用 UDP 和 DCCP 进行测试(仍然使用 md5sum 比较)......

对于 tcpdump 命令,您应该更改-s 1500-s 0,这意味着unlimited。使用该 tcpdump 命令,您可以相信它没有看到它没有发送/接收的数据。另一件好事是比较发送方和接收方的 tcpdump 输出。这样您就可以知道两个网络堆栈之间是否发生了一些数据包丢失。

于 2010-07-30T15:20:09.243 回答
3

您有 x 期限访问权限吗?改用Wireshark并尝试一下——它是免费的、开源的,并且可能比今天的 tcpdump 使用更广泛。(它以前被称为 Ethereal。)

另外,请尝试以下 tcpdump 选项:

  • -xx 也打印数据包的链接头和数据(-w 是否写入数据?)
  • -C 明确指定最大文件大小。
  • -U 将数据包逐个写入文件而不是刷新缓冲区。
  • -p 不要将网卡置于混杂模式
  • -O 不要使用数据包匹配优化器,因为你的是一个新的应用级协议。
  • 您是否在 tcpdump 中使用详细输出?这可以使缓冲区快速填满,因此在运行时将 stdout/err 重定向到文件。

这些千兆以太网卡在两端吗?

于 2010-08-01T23:57:24.903 回答
2

tcpdump被全世界成千上万(至少)程序员和计算机安全专业人员用作诊断和取证工具。当像这样的工具似乎对一项非常常见的任务处理不当时,首先要怀疑的是您编写的代码,而不是工具。

在这种特殊情况下,您的代码有各种各样的重大错误。特别是,使用 TCP,无论客户端是否发送任何数据,您的服务器都会继续将数据写入文件。

此代码具有在某些情况下会导致非确定性行为的竞争条件,不正确地将'\0'其视为网络数据中的特殊值,忽略错误条件,并忽略文件结束条件。这只是一个简短的阅读。

在这种情况下,我几乎可以肯定它tcpdump运行良好,并告诉您您的应用程序没有按照您的想法执行。

于 2010-08-04T02:52:54.450 回答
2

“这是客户端需要将文件发送到套接字的时间。然后它停止,即使服务器继续接收文件并将其写入硬盘驱动器。”

这听起来真的很奇怪。套接字缓冲区太小而不允许这种情况发生。我真的认为您的服务器代码似乎只接收数据,而发送方实际上已经停止发送数据。

于 2010-08-04T09:19:07.067 回答
0

我知道这可能听起来很傻,但你确定这不是文件的 flush() 问题吗?即数据仍在内存中,尚未写入磁盘(因为它们的数量不足)。

尝试sync或稍等片刻,直到您确定已经传输了足够的数据。

于 2010-08-03T10:28:29.910 回答