在C中编程套接字,发送和接收文件时出错

时间:2012-05-16 18:14:39

标签: c sockets

我在C环境下为Linux环境做了一个应用程序。这个程序有效,但之后 一段时间(或多或少5小时)其表现不稳定。 这是背景。我有一些远程计算机(400多个或 每5分钟通过套接字(我的应用程序)发送数据。所有 进程是一个循环,我需要整天工作。该应用程序首先发送 数据(如果存在)然后接收数据(如果存在)。我的应用有效 像服务器端有一些参数或它像客户端一样工作 与其他论点。在监听状态之后,应用程序作为服务器模式运行, 只等待客户端连接。一旦它连接了客户端, 客户端模式下的应用程序发送一条消息,指示将要发送的消息 数据,然后发送一个连接大小和名称的新消息 服务器端(总是发送64个字节,所以我的应用程序写入64个字节并且在 另一边读取64字节),然后发送数据(文件)。服务器 读取要接收的文件大小和名称的消息(64字节), 拆分消息,将大小存储在变量和文件名中 其他,然后收到文件数据。比较存储的大小 在带有数据大小的变量中,如果一切正常,那么就是 服务器发送消息并将数据存储在具有名称的新文件中 收到之前就是这样。因此,直到最后一个文件将被发送 它

当我的应用程序处于开发状态时,我注意到了一些 小时他们被破坏的消息,我的意思是消息是 不完整或有更多数据,可能是下一个数据。所以 文件数据也是。那么,我如何通过相同的方式发送文件数据 插座??注意:我有一个缓冲区来发送和接收消息,以及 用于发送和接收文件数据的其他缓冲区。

等问题: 原始代码:

int copydata(int readfd, int writefd, int offset, int bytes) {
  char buffer[4096];
  int crbytes = 0, cwbytes = 0, trbytes = 0, twbytes = 0;
  if (offset) {
    if (lseek(readfd, offset, SEEK_CUR) < 0) {
      return -1;
    }
  }
  while ((crbytes = read(readfd, buffer, bytes)) > 0) {
    if (crbytes < 0) {
      return -1;
    }
    trbytes += crbytes;
    //printf("dbgmsg::Readed data <%dB> | Total readed data <%dB>\n", crbytes, trbytes);
    while (crbytes > 0) {
      cwbytes = write(writefd, buffer, crbytes);
      if (cwbytes < 0) {
        return -1;
      }
      twbytes += cwbytes;
      crbytes -= cwbytes;
      //printf("dbgmsg::Written data <%dB> | Total written data <%dB>\n", cwbytes, twbytes);
    }
  }
  return twbytes;
}

此代码用于发送和接收文件数据。发送的一面 data使用我们要发送的文件的文件描述符(to 读取)<readfd>并写入套接字的文件描述符(to 写)<writefd>。接收数据的一方,使用<readfd>来阅读 从套接字文件描述符和<writefd>写入文件 我们要写入数据的文件中的描述符。 如果在使用此功能之前发送了其他消息,则客户端和 服务器将卡在内部“while循环”的末尾,在其他情况下 单词,客户端发送所有文件数据,服务器接收全部 文件数据(在这一点上,收到的数据是完整的,我怎么知道? 因为我可以打开收到的文件)。没有错误,只有一个,“没有消息 想要的类型“。如果我没有在此功能之前发送消息,则一切正常 精细。 要跳过这个小问题,我修改代码,传递文件大小为 参数也是如此,如果是结构,则在两个时间之间写入。

int copydata(int readfd, int filesz, int writefd, int offset, int bytes) {
  char buffer[4096];
  int crbytes = 0, cwbytes = 0, trbytes = 0, twbytes = 0;
  if (offset) {
    if (lseek(readfd, offset, SEEK_CUR) < 0) {
      return -1;
    }
  }
  while ((crbytes = read(readfd, buffer, bytes)) > 0) {
    if (crbytes < 0) {
      return -1;
    }
    trbytes += crbytes;
    //printf("dbgmsg::Readed data <%dB> | Total readed data <%dB>\n", crbytes, trbytes);
    while (crbytes > 0) {
      cwbytes = write(writefd, buffer, crbytes);
      if (cwbytes < 0) {
        return -1;
      }
      twbytes += cwbytes;
      crbytes -= cwbytes;
      //printf("dbgmsg::Written data <%dB> | Total written data <%dB>\n", cwbytes, twbytes);
    }
    if (twbytes == filesz) { break; }
  }
  return twbytes;
}

感谢您提前,对不起我的英语!!

1 个答案:

答案 0 :(得分:0)

如果程序遇到“不完整”的write(),你的内部循环会重新发送缓冲区的开头。

while (crbytes > 0) {
      cwbytes = write(writefd, buffer, crbytes);
      if (cwbytes < 0) {
        return -1;
      }
      twbytes += cwbytes;
      crbytes -= cwbytes;
      //printf("dbgmsg::Written data <%dB> | Total written data <%dB>\n", cwbytes, twbytes);
    }

您可以将其更改为:

for ( sentbytes=0; sentbytes < crbytes; sentbytes += cwbytes ) {
      cwbytes = write(writefd, buffer+sentbytes, crbytes - sentbytes);
      if (cwbytes < 0) { return -1; }
      twbytes += cwbytes;
    }