MFC 在工作者线程中创建UDP套接字问题

时间:2022-08-30 11:04:06
本人小白,我在头文件中,作了如下声明
CSocku m_sock;
CWinThread *pThread;
在类外声明函数UINT ThreadFunc(LPVOID lpParam);
其中CSocku是继承了CSocket并重载函数OnReceive在其中接收数据
然后我在cpp文件中
pThread=AfxBeginThread(ThreadFunc,&m_sock);
UINT ThreadFunc(LPVOID lpParam)
{
CSocku *p = (CSocku*)lpParam;
if(!p->Create(1801,SOCK_DGRAM))
{
CString ErrorInfo;
ErrorInfo.Format("创建连接失败:%d",ErrorInfo);
AfxMessageBox(ErrorInfo);
}
return 0;
}

编译不报错,运行出错,设置断点看到程序终止在这一步CSocku *p = (CSocku*)lpParam;
我在主线程中创建套接字可以正常运行,在工作者线程中创建套接字却无法正常运行,本人小白,求各位帮忙

11 个解决方案

#1


CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针

#2


引用 1 楼 oyljerry 的回复:
CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针

本人小白版主大大能不能说的详细一点

#3


引用 1 楼 oyljerry 的回复:
CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针


如果仅仅是参数传递,应该是可以的呀,要出错也应该是create那句出错吧?

#4


CSocket在多线程中使用的时候必须要注意使用正确,因为CSocket的创建跟创建线程有关,其他的线程使用的时候如果用法不对,就找不到创建的那个CSocket的‘句柄’

所以一般不建议在多线程通信中使用CSocket 如果一定要这么做,大致应该是:
1、当前拥有这个CSocket的线程调用Detach方法,使CSocket的句柄和CSocket对象及当前线程脱离关系
2、当前线程把这个Detach返回的SOCKET句柄传递给另外一个线程
3、另外一个线程创建新的CSocket对象,并调用Attach
如:

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
        CSocket socket;
socket.Attach((SOCKET)sock);
//.....
//.....
socket.Detach();
return 0;
}
void CUIxxooDlg::OnOK() 
{
m_Socket.Create();
SOCKET hSocket = Socket.Detach();
DWORD id(0);
::CreateThread(NULL,0,ThreadProc,(LPVOID)hSocket,0,&id);
}

#5


引用 4 楼 lsq19871207 的回复:
CSocket在多线程中使用的时候必须要注意使用正确,因为CSocket的创建跟创建线程有关,其他的线程使用的时候如果用法不对,就找不到创建的那个CSocket的‘句柄’

所以一般不建议在多线程通信中使用CSocket 如果一定要这么做,大致应该是:
1、当前拥有这个CSocket的线程调用Detach方法,使CSocket的句柄和CSocket对象及当前线程脱离关系
2、当前线程把这个Detach返回的SOCKET句柄传递给另外一个线程
3、另外一个线程创建新的CSocket对象,并调用Attach
如:

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
        CSocket socket;
socket.Attach((SOCKET)sock);
//.....
//.....
socket.Detach();
return 0;
}
void CUIxxooDlg::OnOK() 
{
m_Socket.Create();
SOCKET hSocket = Socket.Detach();
DWORD id(0);
::CreateThread(NULL,0,ThreadProc,(LPVOID)hSocket,0,&id);
}

主线程中我没有创建套接字,我直接在工作者线程中初始化AfxSocketInit()并且创建套接字,虽然运行不报错了,但是OnReceive函数貌似没有触发,没收到数据,

#6


一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

#7


引用 6 楼 a18711839961 的回复:
一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

1、AfxSocketInit();是跟框架相关的,你应该把它放到应用程序初始化InitInstance()函数中去
2、你在线程中创建套接字,这个套接字是线程栈对象还是?

#8


引用 7 楼 lsq19871207 的回复:
Quote: 引用 6 楼 a18711839961 的回复:

一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

1、AfxSocketInit();是跟框架相关的,你应该把它放到应用程序初始化InitInstance()函数中去
2、你在线程中创建套接字,这个套接字是线程栈对象还是?

我都不知道啥叫线程栈对象,我先查查资料自己研究一下

#9


有没有搞错,你用工作者线程去创建和连接套接字?我看你的程序貌似运行一遍就线程就完了,如果连接?使用“用户界面”线程去做,这种UDP线程的例程可从CSDN网上下载。

#10


引用 9 楼 wxhxj0268 的回复:
有没有搞错,你用工作者线程去创建和连接套接字?我看你的程序貌似运行一遍就线程就完了,如果连接?使用“用户界面”线程去做,这种UDP线程的例程可从CSDN网上下载。

用户界面线程的UDP通信我很早就已经完成了,我做一个无文档的SDI程序,整个框架可以切换,一共有三个框架,每一个框架有多个视图,这些都已经实现,其中某一个框架要用到UDP通信接收数据,为了让各个框架在运行的时候互不影响,我想在工作者线程中实现UDP通信接收数据并处理。

#11


直接用SOCKET来写已经搞定结贴给分

#1


CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针

#2


引用 1 楼 oyljerry 的回复:
CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针

本人小白版主大大能不能说的详细一点

#3


引用 1 楼 oyljerry 的回复:
CSocku 多线程需要通过Detach,然后线程中Attach来做,不能直接传递指针


如果仅仅是参数传递,应该是可以的呀,要出错也应该是create那句出错吧?

#4


CSocket在多线程中使用的时候必须要注意使用正确,因为CSocket的创建跟创建线程有关,其他的线程使用的时候如果用法不对,就找不到创建的那个CSocket的‘句柄’

所以一般不建议在多线程通信中使用CSocket 如果一定要这么做,大致应该是:
1、当前拥有这个CSocket的线程调用Detach方法,使CSocket的句柄和CSocket对象及当前线程脱离关系
2、当前线程把这个Detach返回的SOCKET句柄传递给另外一个线程
3、另外一个线程创建新的CSocket对象,并调用Attach
如:

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
        CSocket socket;
socket.Attach((SOCKET)sock);
//.....
//.....
socket.Detach();
return 0;
}
void CUIxxooDlg::OnOK() 
{
m_Socket.Create();
SOCKET hSocket = Socket.Detach();
DWORD id(0);
::CreateThread(NULL,0,ThreadProc,(LPVOID)hSocket,0,&id);
}

#5


引用 4 楼 lsq19871207 的回复:
CSocket在多线程中使用的时候必须要注意使用正确,因为CSocket的创建跟创建线程有关,其他的线程使用的时候如果用法不对,就找不到创建的那个CSocket的‘句柄’

所以一般不建议在多线程通信中使用CSocket 如果一定要这么做,大致应该是:
1、当前拥有这个CSocket的线程调用Detach方法,使CSocket的句柄和CSocket对象及当前线程脱离关系
2、当前线程把这个Detach返回的SOCKET句柄传递给另外一个线程
3、另外一个线程创建新的CSocket对象,并调用Attach
如:

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
        CSocket socket;
socket.Attach((SOCKET)sock);
//.....
//.....
socket.Detach();
return 0;
}
void CUIxxooDlg::OnOK() 
{
m_Socket.Create();
SOCKET hSocket = Socket.Detach();
DWORD id(0);
::CreateThread(NULL,0,ThreadProc,(LPVOID)hSocket,0,&id);
}

主线程中我没有创建套接字,我直接在工作者线程中初始化AfxSocketInit()并且创建套接字,虽然运行不报错了,但是OnReceive函数貌似没有触发,没收到数据,

#6


一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

#7


引用 6 楼 a18711839961 的回复:
一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

1、AfxSocketInit();是跟框架相关的,你应该把它放到应用程序初始化InitInstance()函数中去
2、你在线程中创建套接字,这个套接字是线程栈对象还是?

#8


引用 7 楼 lsq19871207 的回复:
Quote: 引用 6 楼 a18711839961 的回复:

一开始我是在主线程中AfxSocketInit();我把这个初始化放到工作者线程中之后,不报错了,但是没有触发OnReceive函数,没收到数据,咋回事? 我不需要在线程中传递套接字,我想直接在工作者线程中创建一个套接字。

1、AfxSocketInit();是跟框架相关的,你应该把它放到应用程序初始化InitInstance()函数中去
2、你在线程中创建套接字,这个套接字是线程栈对象还是?

我都不知道啥叫线程栈对象,我先查查资料自己研究一下

#9


有没有搞错,你用工作者线程去创建和连接套接字?我看你的程序貌似运行一遍就线程就完了,如果连接?使用“用户界面”线程去做,这种UDP线程的例程可从CSDN网上下载。

#10


引用 9 楼 wxhxj0268 的回复:
有没有搞错,你用工作者线程去创建和连接套接字?我看你的程序貌似运行一遍就线程就完了,如果连接?使用“用户界面”线程去做,这种UDP线程的例程可从CSDN网上下载。

用户界面线程的UDP通信我很早就已经完成了,我做一个无文档的SDI程序,整个框架可以切换,一共有三个框架,每一个框架有多个视图,这些都已经实现,其中某一个框架要用到UDP通信接收数据,为了让各个框架在运行的时候互不影响,我想在工作者线程中实现UDP通信接收数据并处理。

#11


直接用SOCKET来写已经搞定结贴给分