用Socket编程,启用线程进行联接为什么会出错?

dreamchild 2003-09-13 04:35:06
1.首先派生自己的Socket类,命名Sock
重载消息函数OnSend
void Sock::OnSend(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类
AfxMessageBox("测试");
CSocket::OnSend(nErrorCode);
}

2.在窗口类中添加一线程函数及一全局Sock变量:
Sock sss;
UINT func(LPVOID pLP)
{
Sock* pInfo=(Sock*)pLP;
pInfo->Connect("www.google.com",80); //随便连上一台服务器,只要有消息框弹出就算成功。
return 0;
}

3.在某个按钮函数中:
sss.Create();
AfxBeginThread(func,&sss);

-----------------------------------------------
运行后的结果会出现错误:
sockcore.cpp文件的867行的一个ASSERT错误
该行为:ASSERT(pState->m_hSocketWindow != NULL);
...全文
45 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
rockersz 2003-09-16
  • 打赏
  • 举报
回复
另外再问一下,我看了一下socket API的文章,请教一下,CSocket类中的OnSend及OnReceive事件在socket API对应要如何实现?也就是说我要如何知道有数据到来?
-----
看看WSAAsyncSelect()msdn的帮助文件
dreamchild 2003-09-16
  • 打赏
  • 举报
回复
ufox,谢谢您,你给的代码真的非常有效。
但我还想问一下,您上边说的
"我也被这个问题困扰了很久,最后决定使用socket API"
你不是已经知道问题的解决方法了吗?为何还要使用socket API?

另外再问一下,我看了一下socket API的文章,请教一下,CSocket类中的OnSend及OnReceive事件在socket API对应要如何实现?也就是说我要如何知道有数据到来?
lostgdi731 2003-09-14
  • 打赏
  • 举报
回复
说了那么多,好象有点离题了,到底是什么问题呢?
ufox 2003-09-13
  • 打赏
  • 举报
回复
不能去掉。有一个解决办法,就是你创建Socket要在线程内部开始创建(但该线程内创建的Socket不能工其他线程使用),而且线程种还要负责把Soceet的消息抛出到应用程序的窗口中去,如下:
CMySocket* pSocket;
...

ThreadFunc( )
{
pSocket = new CSocket;
pSocekt->Create();
pSocket->Connect(...);

while(...)
{
MSG msg;
Sleep( 5 );
if ( ::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE ) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}

。。。 //线程的其他代码
);
}

如果要处理Socket断开重新连接,则必须在该线程中重新建立连接
如果在动态苦中,假如加入语句有用
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()
// setup maps and lists specific to socket state
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandle == NULL)
pState->m_pmapSocketHandle = new CMapPtrToPtr;
if (pState->m_pmapDeadSockets == NULL)
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNotifications == NULL)
pState->m_plistSocketNotifications = new CPtrList;
#endif


}

dreamchild 2003-09-13
  • 打赏
  • 举报
回复
那可不可以干脆把
ASSERT(pState->m_hSocketWindow != NULL);
这一行去掉?
ufox 2003-09-13
  • 打赏
  • 举报
回复
CSocket以及其基类在线程中和动态库中直接使用必定会出上面的错误,他只能在但线程中直接使用。这CSocket以及其基类的bug,参见MSDN的文章“PRB: Assertion Failed on Line 837 - Sockcore.cpp”(通过在MSDN的搜索中,输入上面的就能找到)。上面提供了解决办法,不过用起来很不爽。
我也被这个问题困扰了很久,最后决定使用socket API.
如果你在动态库的多线程中使用CSocket,你遇到的问题会更多
dreamchild 2003-09-13
  • 打赏
  • 举报
回复
我用MFC写的啊,如果不用线程的话,把线程中的函数部分放于按钮函数中就 不会出现这个错误了。
好像是我想的多线程Socket模型错了,并非是这样子进行多线连接的
feeboby 2003-09-13
  • 打赏
  • 举报
回复
是不是在主窗口实例化之前就开始了处理窗口函数

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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