【问题标题】:client-server programme客户端-服务器程序
【发布时间】:2013-01-18 18:29:26
【问题描述】:

我们在 UNIX 环境中制作了简单的 client.cserver.c 程序。我们使用它传输一个简单的文本文件,首先打开它,然后读取它并使用openreadsend系统调用发送;在客户端,我正在接收它,并通过在服务器机器上创建一个文件来编写它。传输进行得很顺利,但在客户端收到的文件与服务器端的文件并不完全相同。在可读字符之间有一些不可读的字符。你能告诉我这可能是什么原因吗?虽然文件的大部分内容相同,但只有一小部分之间存在一些差异。

代码可见here

谢谢!

服务器端循环:

do
{
    n=read(t,buf,100);
    write(1,buf,strlen(buf));
    send(connected, buf,strlen(buf), 0);    
} while(n!=0);

在客户端

do
{
    bytes_recieved=recv(sock,recv_data,100,0);
    count=write(t,recv_data,strlen(recv_data));     
} while(bytes_recieved!=0);

【问题讨论】:

  • 请展示您的代码(或相关的sn-ps,尤其是读写循环)
  • 我应该在哪里粘贴代码。我应该只通过编辑问题将其粘贴到这里。对不起这个问题,但我相对于这个论坛,如果我们的东西太长或什么的,很多人会感到恼火他们可能不喜欢。谢谢
  • 如果代码很多,你可以使用某种粘贴板并添加链接。如果是少量代码,可以直接放在问题中。无论哪种方式,您都应该编辑此问题并添加新信息。
  • 可能有很多问题,但我们需要看到比您发布的更多的代码。可能是 buf 太小而无法读取您已读入的文件的 100 字节,或者 recv_data 太小而无法从套接字读取 100 字节。事实上,还有很多潜在的问题,但我们需要看到更多的代码。
  • 我马上看到的一个问题是您正在使用 strlen(buf)... buf 101 bytes memset 为 0 吗?你应该总是写 n,而不是 strlen(buf),因为 read 可能返回的字节数可能少于 100 个字节。另外,出于同样的原因发送 n。

标签: c


【解决方案1】:

首先,不要使用strlen()。绝对不能保证文件流中的任何地方都会有一个 NUL 字节,事实上,对于文本文件,永远不应该有。

每次循环时,您都应该输出实际接收到的字节数,而不是strlen() 认为缓冲区中可能存在的字节数:

do
{
    bytes_received = recv(sock, recv_data, 100, 0);
    if (bytes_received < 0) {
        perror("read");
        break;
    } else if (bytes_received == 0) {
        break;
    } else {
        count = write(t, recv_data, bytes_received);
        // in theory - add error check here too!
    }
} while (count > 0);

【讨论】:

  • 我已经删除了 strlen 并替换为实际的 recv 返回,但仍然存在一些(少数)不可读字符的相同问题。我的第二个问题是我们可以使用相同的机制发送二进制文件或任何其他文件吗喜欢歌曲和视频,或者我们需要更改程序来发送这些文件。谢谢!
  • 您需要更改另一半代码以不使用 strlen() - 我只展示了一半。一旦正确,它将传输任何文件,无论类型如何。
【解决方案2】:

您应该检查您的 send() 以查看它们是否成功。您可能会发现在某些时候写入缓冲区(即套接字的输出缓冲区)已满并且发送失败。这是正常行为。 Send 返回发送的字节数。如果您不发送多字节字符,这可能会表现为丢失数据而不是损坏数据。如果您丢失了两个字节字符中的一个字节,可能会导致损坏。

【讨论】:

    【解决方案3】:

    MS Windows 系统使用回车换行作为换行符,linux 只使用换行符。

    “不可读的字符”是Ctrl-M,回车,字符号13。

    【讨论】:

    • 除非他们的代码这样说,否则不是。 stdio 有时会进行 CRLF/CR 转换,但读/写系统调用不会。
    • 附注他还说这是在UNIX下
    • 你不知道。根据 OP,环境是 UNIX。他们没有将 Windows 客户端称为 UNIX 服务器。它可能很容易缓冲问题或其他损坏。直到他们发布一些东西我们才能知道。
    • 当我回答这个问题时,OP 没有发布任何代码。我唯一需要做的是 OP 的声明,即“在可读字符之间有一些不可读的字符”。我只是想消除显而易见的东西。
    • 我认为这通常在 cmets 中做得更好,这样对于困惑的新手就不会产生误导性的答案:)
    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2020-07-28
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多