-1

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

文件名是从命令参数转换而来的,格式类似于“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);

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

4

1 回答 1

0

正如 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, ...

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

于 2015-11-23T15:37:37.540 回答