Socket accept正在windows上消耗内存而未释放

Socket accept正在windows上消耗内存而未释放,c,windows,sockets,gcc,memory-management,C,Windows,Sockets,Gcc,Memory Management,我用C编写了一个非常小的函数,打开一个套接字,接受连接并立即关闭它们 问题是,每个连接都会占用一些内存,而不会在任何时候将其释放到操作系统。我用大约300K个请求运行了ab(apachebenchmark),进程内存在不断增长(最后是几百兆字节) 我知道进程并不总是将其空闲内存返回操作系统。但一旦超过几兆字节,我认为它应该返回内存,还是我错了 这只发生在Windows上。在Linux上,我的内存使用率一直接近进程启动使用率 使用GCC 4.8.2编译。在Windows Server 2008 R

我用C编写了一个非常小的函数,打开一个套接字,接受连接并立即关闭它们

问题是,每个连接都会占用一些内存,而不会在任何时候将其释放到操作系统。我用大约300K个请求运行了ab(apachebenchmark),进程内存在不断增长(最后是几百兆字节)

我知道进程并不总是将其空闲内存返回操作系统。但一旦超过几兆字节,我认为它应该返回内存,还是我错了

这只发生在Windows上。在Linux上,我的内存使用率一直接近进程启动使用率

使用GCC 4.8.2编译。在Windows Server 2008 R2和Windows 8.1上测试

void http_server_start(void) {
  int rc;
  struct sockaddr_in cfg;

  #ifdef _WIN32
  WORD ver;
  WSADATA data;
  ver=MAKEWORD(2,2);
  rc=WSAStartup(ver, &data);
  if(rc != 0){
    printf("Error: Unable to initialize WSA (%d)", rc);
  }
  #endif

  memset(&cfg, 0, sizeof(cfg));
  cfg.sin_family = AF_INET;
  cfg.sin_addr.s_addr = htonl(INADDR_ANY);
  cfg.sin_port = htons(PORT);
  server = socket(AF_INET, SOCK_STREAM, 6);
  int reuseaddr=1;
  if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr)) == -1){
    rc=GetLastErrorEx();
    printf("Error: Unable to set SO_REUSEADDR (%d)\n", rc);
  } else if (bind(server, (struct sockaddr *)&cfg, sizeof(cfg)) < 0 ) {
    rc=GetLastErrorEx();
    printf("Error: Unable to bind socket (%d)\n", rc);
    close(server);
  } else if (listen(server, QUEUE_SIZE) < 0) {
    rc=GetLastErrorEx();
    printf("Error: Unable to listen (%d)\n", rc);
    close(server);
  } else {
    printf("Listening on %s:%d\n", inet_ntoa(cfg.sin_addr), ntohs(cfg.sin_port));
    int client;
    struct sockaddr_in addr;
    int addrlen=sizeof(addr);
    do {
      client=accept(server, (struct sockaddr*)&addr, &addrlen);
      if(client != -1){
        shutdown(client, SHUT_RDWR);
        close(client);
      }
    } while(1);
  }
}
void http\u服务器\u启动(void){
int rc;
cfg中的结构sockaddr_;
#ifdef_WIN32
单词ver;
WSADATA数据;
ver=生成词(2,2);
rc=WSAStartup(版本和数据);
如果(rc!=0){
printf(“错误:无法初始化WSA(%d)”,rc);
}
#恩迪夫
memset(&cfg,0,sizeof(cfg));
cfg.sin_family=AF_INET;
cfg.sin_addr.s_addr=htonl(INADDR_ANY);
cfg.sin_port=htons(port);
服务器=套接字(AF_INET,SOCK_STREAM,6);
int=1;
if(setsockopt(服务器,SOL_套接字,SO_REUSEADDR,(char*)和REUSEADDR,sizeof(REUSEADDR))=-1){
rc=GetLastErrorEx();
printf(“错误:无法设置SO\u REUSEADDR(%d)\n)”,rc);
}else if(bind(server,(struct sockaddr*)&cfg,sizeof(cfg))<0){
rc=GetLastErrorEx();
printf(“错误:无法绑定套接字(%d)\n”,rc);
关闭(服务器);
}else if(侦听(服务器、队列大小)<0){
rc=GetLastErrorEx();
printf(“错误:无法侦听(%d)\n”,rc);
关闭(服务器);
}否则{
printf(“侦听%s:%d\n”、inet_ntoa(cfg.sin_addr)、ntohs(cfg.sin_端口));
int客户端;
地址中的结构sockaddr\u;
int addrlen=sizeof(addr);
做{
client=accept(服务器,(结构sockaddr*)&addr,&addrlen);
如果(客户端!=-1){
关闭(客户端,关闭\RDWR);
关闭(客户);
}
}而(1),;
}
}

要关闭套接字,请使用shutdown()和close()。 实际上,shutdown()强制终止连接,即使存在 指同一插座的多个描述符, shutdown()只允许在一个方向上关闭,close()不允许 影响连接状态,直到最后一个描述符 关闭

试用

 int closesocket(Socket S);

应用程序每次成功调用socket时都应该有一个对closesocket()的匹配调用,以将任何套接字资源返回到系统。

在Windows上,winsock使用
closesocket
来正确关闭和清理套接字。

如果在Windows上使用
closesocket
而不是
close
,会发生什么,这是一个快速的。这就解决了问题,你介意把它作为答案贴出来让我接受吗?:)