1

我在 C for 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;
}

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

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;
}

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

4

1 回答 1

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;
    }
于 2012-05-16T21:03:23.080 回答