使用socket连接服务器的内存泄露问题,有代码

blldw 2012-08-07 02:47:08
以下代码可在vs2008下编译通过,其中61.135.169.125为百度网站的IP地址,作为测试用。程序产生的问题在于,当用任务管理器查看程序耗占的内存时,发现耗占内存以8K,12k或者更大的数值持续增加。不知道是哪里有问题。请大家提出看法,谢谢~~~~
#include <iostream>
#include <Windows.h>
#include <WinSock2.h>

int main(int, char**)
{
while (true) {
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("61.135.169.125");
addr.sin_port = htons(80);
if (connect(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
std::cout << "connect error" << std::endl;
}
shutdown(s, SD_SEND);
closesocket(s);
}

return 0;
}
另外同样的问题,但是是boost库中使用asio的,请参见
http://topic.csdn.net/u/20120804/01/fb5259bf-f15c-4062-a7fe-3ef52d0d6305.html?73283
...全文
278 点赞 收藏 9
写回复
9 条回复
blldw 2012年08月08日
使用死循环的目的是加快程序运行进度,用于测试目的,而且在实际程序中,确有多个线程同时尝试连接到不同的服务器,短时间内的效果与循环差异不大.经过大家的解答,感觉的确是socket描述符占用的资源短不能在closesocket后立即被释放,导致程序内存耗占越来越多。难道没有其它解决方法吗,socket选项有无作用?
回复 点赞
傻X 2012年08月08日
遇到过,以前我写的守护进程程序经常要重启服务端程序,就会碰到类似的问题,大概需要10-30秒之间才会完全释放。因为是守护程序的关系,我失败后过一段时间会再连。因此问题不是很大
回复 点赞
blldw 2012年08月08日
实际上我是想扫描一个网段的计算机,线程池中一个线程扫描一个IP地址,由于每个线程不断地创建socket,而且该线程在非常短时间就结束了(5秒钟以内),一方面导致socket资源不能被立即释放导致内存持续增加,另外一方面就是导致本地连接远程的socket端口被使用殆尽,导致后继操作出错。想到了一个解决方式是socket复用方式,即一个线程始终使用自己维护的一个socket,并通过SO_REUSEADDR选项始终使用某一个端口进行远程连接,但是也出现了WSAEADDRINUSE错误。感觉这是一个比较普遍的问题,大家没遇到过吗?有什么解决方法吗?
回复 点赞
傻X 2012年08月08日
测试1小时-2小时,以前我写的代码,开3天都内存都没增长过。
实在不行用CheckBounds查查看吧
回复 点赞
blldw 2012年08月07日
int total = 0;
while (total++ < 10000) {
// ...
}

std::cout << "input for total:";
std::cin.get();
WSACleanup( );

我连接目标服务器10000次,在此过程中发现程序耗占内存从1000K升至2500K,在等待用户输入值时,我一直等待了20分钟,但是发现耗占内存没有丝毫减少。多久后套接字资源才被释放?1小时,2小时?
回复 点赞
zhiweiyouzhishenghuo 2012年08月07日
貌似closesocket只是说那个套接字不可以用了,它实际占用的资源需要一定的时间才能释放掉的。
你可以用防火墙看看,每次申请到的socket套接字会不断上涨,然后过一段时间又会从很小的数值开始上涨。
因为你刚刚关掉的套接字,必须要等一段时间才能释放掉所有的资源。
回复 点赞
Gloveing 2012年08月07日
倒不是很占内存,也没有持续增长,只是你的一个while循环,太耗CPU。。。
回复 点赞
Gloveing 2012年08月07日
先还得初始化套接字库:
//================================================================= 

#include <WinSock2.h>
#include <Windows.h>
#include <iostream.h>

#pragma comment(lib,"ws2_32.lib")

void InitSocket()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}


if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
}

void main(int, char**)
{
InitSocket();

while (true) {
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("61.135.169.125");
addr.sin_port = htons(80);
if (connect(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
cout << "connect error" <<endl;
}
shutdown(s, SD_SEND);
closesocket(s);
}

WSACleanup( );
return ;
}
回复 点赞
hurryboylqs 2012年08月07日
你写的死循环啊,Debug吧,内存增长很正常,只要不一直增下去即可,connect完一次Sleep(1000)试试还会不会不断增
回复 点赞
发动态
发帖子
网络编程
创建于2007-09-28

7880

社区成员

6.4w+

社区内容

VC/MFC 网络编程
社区公告
暂无公告