【问题标题】:error in receiving char[] in UDP, under circumstance with packet loss在丢包的情况下,在 UDP 中接收 char[] 时出错
【发布时间】:2016-02-24 19:16:41
【问题描述】:

客户端先发送文件名,服务器用该名称创建一个文件来写入数据。

文件名是从命令参数转换而来的,格式类似于'file.txt'。问题是每次我投射除'.txt'以外的文件名时都会发生错误。

我在丢包的情况下测试代码,概率为 15%。如果发生丢失,整个数据包将消失,不会留下任何部分。这就是为什么我认为文件名每次都丢失的原因。如果文件名包没有丢失,文件将以正确的名称打开。所以我认为它至少每 10 次会收到一个合适的,但它从来没有。

//send the file name to the server
byteSent = sendto(sockfd, argv[3], sizeof(argv[3]), 0,
        (struct sockaddr*)&addr, addr_size);

我猜这些变量没有任何其他问题。当不假设丢包时,它按我预期的方式工作。我从 strlen(argv[3]) + 1 更改了第三个参数,但没有任何改变。

if((byteRcvd = recvfrom(sockfd, buf, sizeof(buf), 0,
    (struct sockaddr*)&addr, &addr_size)) < 0)
    exit(1);
byteRcvd = BUFFER_SIZE;

fp = open(buf, O_RDWR | O_CREAT, 0644);
    //printf("file \"%s\" is opened\n", buf);

我可以通过修改代码来解决这个问题吗?

【问题讨论】:

  • 没有。您需要基于对网络的充分理解,完全重新设计它。您忽略的最明显的一点是 UDP 可以乱序传送数据包,因此您可以在文件名之前获取数据,并且写入通过不安全的网络连接提供的任意、未经检查的文件名是非常不安全的。
  • 另外,您正在向字符发送一个指针。这个指针在接收过程中没有任何意义。

标签: c sockets packet-loss


【解决方案1】:

正如 Chris Stratton 在评论中所写 - 您的大部分代码都应该更改。您的文件传输协议的设计是幼稚的。有很多潜在的问题

  • UDP 传送数据包的顺序可能与发送方发送它们的顺序不同。
  • 服务器无法识别哪些数据报包含文件数据以及哪些数据报包含文件名。
  • 服务器无法识别文件结束位置。但您可能只需要传输适合一个数据报的小文件。
  • 服务器可以覆盖任何文件而无需任何客户端身份验证。
  • 服务器无法识别来自不同客户端的数据。

还有一个你最初可能问过的小问题:

byteSent = sendto(sockfd, argv[3], sizeof(argv[3]), 0, ...

argv[3]char* 并且 `sizeof(char*) 是 4 或 8 个字节。应该是吧

byteSent = sendto(sockfd, argv[3], strlen(argv[3]) + 1, 0, ...

警告:请勿在其他人可以连接到服务器机器的环境中进行测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多