C Socket服务器,内存随着文件写入而增加

我有一个用C编写的简单的服务器程序,程序运行在Ubuntu Linux发行版上。 该程序旨在侦听客户端发送的消息,将这些消息写入文件(每个消息放入一个单独的文件中),并在接收并存储消息后,将确认信息发送回客户端。

我注意到,随着服务器继续接收和存储消息,可用系统内存的数量迅速减less并且持续减less直到消息停止。 没有消息发送时,内存保持不变。 不过,我也注意到我可以通过从磁盘上删除写入的文件来重新释放内存(即使服务器仍在运行,我也可以这样做)。 我因此导致相信内存问题与我的文件操作有关,尽pipe我看不到写入文件的代码有任何问题。

有人可以帮忙吗?

注:我正在观察“top”的内存使用情况。

我已经收录了节目的摘录。 下面的函数处理来自客户端的input并将该信息写入文件。 这是我目前认为的问题所在:

void handleinput (int sock) { char filename[strlen(tempfolder) + 27]; generatefilename(filename); int rv; int n = 1; int received = 0; char buffer[BUFFER_SIZE]; FILE *p = NULL; fd_set set; char response[768]; struct timeval timeout; timeout.tv_sec = 360; timeout.tv_usec = 0; FD_ZERO(&set); FD_SET(sock, &set); bzero(buffer, BUFFER_SIZE); bzero(response, sizeof response); rv = select(sock + 1, &set, NULL, NULL, &timeout); if (rv == -1) { error("error on select in handleinput"); close(sock); exit(1); } else if (rv == 0) { close(sock); exit(0); } else { n = read(sock, buffer, BUFFER_SIZE-1); if (n <= 0) { close(sock); exit(0); } } // open file if (n != 0) { p = fopen(filename, "a"); if (p == NULL) { error("ERROR writing message to file"); close(sock); exit(1); } } // loop until full message is received while (n != 0) { if (n < 0) { error("ERROR reading from socket"); close(sock); exit(1); } received = 1; // write content to file fwrite(buffer, strlen(buffer), 1, p); if (buffer[strlen(buffer)-1] == 0x1c) { break; } bzero(buffer, BUFFER_SIZE); rv = select(sock + 1, &set, NULL, NULL, &timeout); if (rv == -1) { error("ERROR select in loop in handleinput"); close(sock); exit(1); } else if (rv == 0) { close(sock); exit(0); } else { n = read(sock, buffer, BUFFER_SIZE-1); } } // close file if we opened it earlier if (p != NULL) { fclose(p); } // send acknowledgement back to client if (received == 1) { generateResponse(response, filename); n = write(sock, response, strlen(response)); if (n < 0) { error("ERROR writing to socket"); close(sock); exit(1); } } } 

这是因为写作的缓存机制。 如果有很多客户端正在尝试写入文件,则IO缓冲区将填充内核内存,但直到关闭套接字或缓冲区填充后才会写入该文件。 你可以通过刷新缓冲区来解决这个问题。 其他人提出的建议是摆脱stdio中的写入和读取包装,只使用内核调用写入,因为这将有助于性能,并可能自动刷新缓冲区。

你可以刷新fsync()顺便说一句。