accept莫名奇妙的崩溃,请教大家!

wjb_yd 2010-09-10 09:51:00

WORD VersionRequested;
WSADATA WsaData;

GuidToCommuKey.clear();
GuidToCommuTime.clear();

VersionRequested = MAKEWORD(2, 0);

if (WSAStartup(VersionRequested, &WsaData))
{
anchor::dprintf("加载socket库失败!\n");
return -1;
}

assert(SDR_OK == SDF_OpenDevice(&pDeviceHandle));
assert(SDR_OK == SDF_OpenSession(pDeviceHandle, &pSessionHandle));

SOCKADDR_IN local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(PORT);

SOCKET Listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (Listen == INVALID_SOCKET)
{
anchor::dprintf("socket初始化失败!\n");
closesocket(Listen);
WSACleanup();
return -1;
}

if (bind(Listen,(sockaddr*)&local, sizeof(local)) != 0)
{
anchor::dprintf("socket绑定失败!\n");
closesocket(Listen);
WSACleanup();
return -1;
}

if (listen(Listen, LISTEN_NUM) != 0)
{
anchor::dprintf("socket监听失败!\n");
closesocket(Listen);
WSACleanup();
return -1;
}

// 从本地配置文件中读取数据库配置信息
//GetDataBaseParam();
//
//if (! DataBase::GetInstance()->Initialize())
// return -1;

//if (! DataBase::GetInstance()->ConnectDataBase(host, user, passwd, database, port))
// return-1;

// 从数据库中读取服务器运行参数
if (! GetServerRunParam())
return -1;

while (1)
{
SOCKET NewSocket = accept(Listen, NULL, NULL);

if (INVALID_SOCKET == NewSocket)
{
anchor::dprintf("\n接受socket连接请求失败:%d\n", WSAGetLastError());
closesocket(NewSocket);
continue;
}
else
{
int TimeOut = SOCKET_TIME_OUT;
if (setsockopt(NewSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&TimeOut, sizeof(TimeOut)) == SOCKET_ERROR)
continue;

if (setsockopt(NewSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&TimeOut, sizeof(TimeOut)) == SOCKET_ERROR)
continue;
}

unsigned int ThreadId;
HANDLE handle = (HANDLE)_beginthreadex(NULL, 0, CommuicateWithClient, (void*)NewSocket, 0, &ThreadId);

if (handle)
CloseHandle(handle);
}

closesocket(Listen);
WSACleanup();

return 0;


这段代码有很低的几率,会在SOCKET NewSocket = accept(Listen, NULL, NULL);这一行崩溃,崩溃的原因是访问了空指针。
但是我实在想不出来,那一行哪里会访问空指针。由于概率很低,所以很难调试。
请教大家一下,有没有遇到过类似的bug,或者帮我出个主意,怎么跟踪这个崩溃,谢谢了!
...全文
404 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjb_yd 2010-09-17
  • 打赏
  • 举报
回复
结贴了吧
regainworld 2010-09-13
  • 打赏
  • 举报
回复
网线松了或防火墙之类的外部原因,导致套接字失效
wjb_yd 2010-09-12
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 arong1234 的回复:]
checkesp的检查不可能检查出所有的问题.感觉accept如果报的准确,说明socket内部某些结构被破坏了,这也说明有内存访问越界的可能.closesocket之类的方法不一定可靠,内存访问越界如果找不到原因,你会见到各种稀奇古怪的错误的

引用 16 楼 wjb_yd 的回复:
引用 14 楼 arong1234 的回复:
怀疑栈被破坏了,没有正确反映crash情况。注意看看是不是……
[/Quote]

嗯,我也觉得肯定是哪里内存写越界了,导致栈被破坏了,就是不知道怎么把它揪出来。
FlyingBlueBoy 2010-09-10
  • 打赏
  • 举报
回复
closehandle 为减少引用计数,并不关闭线程。
除非你下面又要使用该线程HANDLE,不使用时最好关闭.
详细可看核心编程。
wujiabao 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 visualeleven 的回复:]
你上面的bind,listen判断都不对啊?失败的话,返回值是SOCKET_ERROR(-1),下面的没有看
[/Quote]
判断是对的, 失败的话 -1, 成功的话是 0, 所以判断没有问题, 应该是其它问题。
Eleven 2010-09-10
  • 打赏
  • 举报
回复
你上面的bind,listen判断都不对啊?失败的话,返回值是SOCKET_ERROR(-1),下面的没有看
wujiabao 2010-09-10
  • 打赏
  • 举报
回复
代码没看出来什么问题, 你看看在调用accept之前的Listen是不是为NULL, 你的SOCKET句柄干嘛起这个名子, 很能混淆人。
zerostudy 2010-09-10
  • 打赏
  • 举报
回复
我只是好奇,为什么刚建立线程就CloseHandle(handle);了~~
看windows核心编程,因为我也不会说,,。,

同上,,
dukelee 2010-09-10
  • 打赏
  • 举报
回复
把那句accept调用改一下,加个sockaddr变量去接收地址信息,函数返回时要去填写这个地址
SOCKET accept(
__in SOCKET s,
__out struct sockaddr* addr,
__in_out int* addrlen
);

addr
An optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family that was established when the socket from the sockaddr structure was created.

addrlen
An optional pointer to an integer that contains the length of structure pointed to by the addr parameter.

hastings 2010-09-10
  • 打赏
  • 举报
回复
我只是好奇,为什么刚建立线程就CloseHandle(handle);了~~
arong1234 2010-09-10
  • 打赏
  • 举报
回复
checkesp的检查不可能检查出所有的问题.感觉accept如果报的准确,说明socket内部某些结构被破坏了,这也说明有内存访问越界的可能.closesocket之类的方法不一定可靠,内存访问越界如果找不到原因,你会见到各种稀奇古怪的错误的[Quote=引用 16 楼 wjb_yd 的回复:]
引用 14 楼 arong1234 的回复:
怀疑栈被破坏了,没有正确反映crash情况。注意看看是不是有内存越界访问,accept不像会造成crash的函数


问题是,我是在debug模式下跑的,vc每次执行完一个函数都会check esp的,但是从来没报过栈损坏。
我也很奇怪,按理说这socket都用了这么多年了,怎么可能到我这儿就崩溃了。
[/Quote]
wjb_yd 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 jhlong 的回复:]
是运行很长时间崩溃的还是会很快崩溃?

另外建议楼主在另外两个 continue之前也 closesocket()一下
[/Quote]
一下午崩一次
jhlong 2010-09-10
  • 打赏
  • 举报
回复
是运行很长时间崩溃的还是会很快崩溃?

另外建议楼主在另外两个 continue之前也 closesocket()一下
wjb_yd 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 arong1234 的回复:]
怀疑栈被破坏了,没有正确反映crash情况。注意看看是不是有内存越界访问,accept不像会造成crash的函数
[/Quote]

问题是,我是在debug模式下跑的,vc每次执行完一个函数都会check esp的,但是从来没报过栈损坏。
我也很奇怪,按理说这socket都用了这么多年了,怎么可能到我这儿就崩溃了。
TRUE 2010-09-10
  • 打赏
  • 举报
回复
应该是由于你的代码 if (! GetServerRunParam())
return -1;
造成了listen是个空指针或者是非常的指针,因此你可以把这个代码屏蔽掉,然后再看看,如果还有问题,你就在上面的bind,listen 的后面加上 WSAGetLastError 看看返回的数值是多少?
arong1234 2010-09-10
  • 打赏
  • 举报
回复
怀疑栈被破坏了,没有正确反映crash情况。注意看看是不是有内存越界访问,accept不像会造成crash的函数
wjb_yd 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 arong1234 的回复:]
你怎么知道是因为“空指针”导致crash的?怎么知道是在accept那crash的?
[/Quote]

崩溃的时候,vc提示的,而且崩溃的代码就在accpet调用的地方,不过崩溃在比较深的tcpip内核调用栈了,没有pdb,看不到具体的崩溃代码。
arong1234 2010-09-10
  • 打赏
  • 举报
回复
你怎么知道是因为“空指针”导致crash的?怎么知道是在accept那crash的?
arong1234 2010-09-10
  • 打赏
  • 举报
回复
accept不需要一个指针来接受数据[Quote=引用 9 楼 xhk456 的回复:]
你传的本来就是空指针呀 。。。。
[/Quote]
arong1234 2010-09-10
  • 打赏
  • 举报
回复
只要你不需要句柄,你就应该close它,这样可以节省句柄表的空间。线程自己保留了对内核对象的引用,因此不需要你保留一个handle让它运行[Quote=引用 1 楼 hastings 的回复:]
我只是好奇,为什么刚建立线程就CloseHandle(handle);了~~
[/Quote]
加载更多回复(2)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧