关于Socket10093错误

KWHOK 2009-08-24 12:55:53
问题描述:

基于MFC对话框的程序,在程序运行出示化时,成功调用WSAStartup(),socket版本2.2,
之后开辟一个tcp的监听连接的线程,代码如下:


// tcp listen thread
......
listen(sListenSocket, 1);
while(!m_ThreadTermined) //在主线程中,控制此变量的改变
{
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(sListen, &fdSocket);

int nRet = ::select(0, &readSocket, 0, 0, &waitTime); //waitTime 设置1s
if (nRet<0)
AfxMessageBox("Failed select()");
else if(nRet ==0) //time out
continue;
else
{
Logger::getInstance()->error("nRet: %d\n", &nRet); //发现既是没有连接过来,结果总是1
Logger::getInstance()->error("Error: %d\n", GetLastError()); // 总是0
if(FD_ISSET(sListen, &readFD))
{//接受连接
sClient = ::accept(sListen, (sockaddr *)&clientAddr, &cAddrLen);
if(sClient == INVALID_SOCKET)
{
char chMsgBuffer[100];
wsprintf(chMsgBuffer, "\nWinsock error %d: TCP Faild accept()\n\n", GetLastError());//10093
Logger::getInstance()->error(chMsgBuffer);
continue;
}
。。。。。
}
}
}


现在问题是: 运行程序,直接点击关闭按钮,没有任何客户端连接进来,上述监听线程总会进入到accept()代码段,在日志里记录下错误信息, 个人觉得select()不应该返回1,且进入accept()。
另外,我是在主线程OnDestroy()销毁里,设置的m_ThreadTermined=false; 如果在设置false后,Sleep(5s)则监听线程会执行完毕,正常退出,此时绝不会进入accept()那段代码。
如此,便是当主线程里设置m_ThreadTermined=false时,监听线程正处在select()等待连接状态,这时,主线程退出,监听线程强制关闭,造成sListen socket某种错误, 进而造成select()取得返回值1, 但是我用GetLastError()没有得到错误号, 而在accept()后调用GetLastError()得到10093错误:

Successful WSAStartup not yet performed.
Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

如上,WSAStartup()正常调用,WSACleanup ()也只一次;

谁能解释一下,为什么出现上述现象! 会进入accept()代码,且10093错误!
...全文
4403 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunStd 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

看10093的错误,应用程序没有调用 WSAStartup,或者 WSAStartup 失败。

你的WSAStartup调用是不是在accept调用之前?
[/Quote]

高手
雪影 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 conry 的回复:]
估计是楼上描述的问题
应该用WaitForSingleObject等待线程结束再WSACleanup
[/Quote]
应该是,主线程会先调用WSACleanup,监听线程还在调用accept,显然会出问题。
调用WSACleanup之前必须确定监听线程已经结束才行。
Conry 2009-08-24
  • 打赏
  • 举报
回复
估计是楼上描述的问题
应该用WaitForSingleObject等待线程结束再WSACleanup
KWHOK 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fandh 的回复:]
楼主的这样调用的确会有问题,在WSACleanup后调用,肯定会出现问题的!
[/Quote]

怎么确定,是在wascleanup()后,调用select的。。
KWHOK 2009-08-24
  • 打赏
  • 举报
回复
如何检测WSACleanup()是否已经被调用呢。。。。
KWHOK 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tttyd 的回复:]
你将m_ThreadTermined设置成false的时候,紧接着是不是要调用了WSACleanup?

在主线程调用了WSACleanup之后,你的监听线程还在工作?
那么在accept处发现系统已经调用了WSACleanup,于是返回10093。
这个不奇怪啊,不知道楼主有什么觉得不对的地方
[/Quote]

我的WSStartup() 和 WSACleanup()是封装在一个类中的构造函数和析构函数中,然后用这个类
在stdafx.h中定义了这个类的一个全局变量,你觉得在线程销毁前全局的变量销毁了。。。
fandh 2009-08-24
  • 打赏
  • 举报
回复
楼主的这样调用的确会有问题,在WSACleanup后调用,肯定会出现问题的!
雪影 2009-08-24
  • 打赏
  • 举报
回复
你将m_ThreadTermined设置成false的时候,紧接着是不是要调用了WSACleanup?

在主线程调用了WSACleanup之后,你的监听线程还在工作?
那么在accept处发现系统已经调用了WSACleanup,于是返回10093。
这个不奇怪啊,不知道楼主有什么觉得不对的地方
KWHOK 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tttyd 的回复:]
看10093的错误,应用程序没有调用 WSAStartup,或者 WSAStartup 失败。

你的WSAStartup调用是不是在accept调用之前?
[/Quote]

正常调用! 见我问题描述部分!
雪影 2009-08-24
  • 打赏
  • 举报
回复
看10093的错误,应用程序没有调用 WSAStartup,或者 WSAStartup 失败。

你的WSAStartup调用是不是在accept调用之前?

18,362

社区成员

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

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