问:关于c++子线程中用socket发送信息不成功的问题

wmnmtm 2011-03-18 02:16:14
void CServerDlg::OnStart()
{
// TODO: Add your control notification handler code here
UpdateData();

if(m_sockSend.Create(m_ServerPort,SOCK_DGRAM,NULL))//创建套接字
{
m_sockSend.Bind(m_ServerPort,m_ServerIP); //绑定本地套接口
SetTimer(1,2000,NULL);//创建一个定时器定时发送
//GetDlgItem(IDC_SEND)->EnableWindow(false);//发送按钮无效
//GetDlgItem(IDC_STOP)->EnableWindow(true);//停止按钮生效
}
else
{
AfxMessageBox("Socket创建失败!");
}

//在这儿开始一个子线程
pThread1=AfxBeginThread(ThreadFunc1,&thdStruct[1]);

}

//下面这个计时器处理可以发送到客户端
void CServerDlg::OnTimer(UINT nIDEvent)
{
CString m_ClientIP="127.0.0.1";
UINT m_ClientPort=8080;
int iSend= m_sockSend.SendTo(szSend,10,m_ClientPort,m_ClientIP,0);//发送UDP数据
CDialog::OnTimer(nIDEvent);
}

//在子线程函数中,为什么老发送不出去,也不提示出错,就好像没发送动作一样
UINT ThreadFunc1(LPVOID lpParam)
{
threadStruct* pwwm=(threadStruct*)lpParam;





int bm;
bm=1;
while (bm)
{

Sleep(2000);

strcpy(szSend,"567");//这句能成功
strcpy(szSend,p); //这句也能成功
CString m_ClientIP="127.0.0.1";
UINT m_ClientPort=8080;
m_sockSend.SendTo("1234",10,m_ClientPort,m_ClientIP,0);//这句好像不存在似的,为什么这句不能发送成功
}
return 0;

}

...全文
337 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eleven 2011-03-18
  • 打赏
  • 举报
回复
还是用winsock API去写吧
celerylxq 2011-03-18
  • 打赏
  • 举报
回复
对了你还可以用抓包软件如wireshark去看是不是真的从本机发出数据了
celerylxq 2011-03-18
  • 打赏
  • 举报
回复
m_sockSend.SendTo("1234",10,m_ClientPort,m_ClientIP,0);//这句好像不存在似的,为什么这句不能发送成功
你看看上句中的m_sockSend的值是不是和你创建socket时m_sockSend的值一样,如果真如1楼说的m_sockSend 是 CServerDlg 的成员变量,那你肯定不能在线程函数(静态全局函数)中调类的成员函数
shenyi0106 2011-03-18
  • 打赏
  • 举报
回复
如果要跨线程使用CAsyncSocket或者CSocket的话,你必须的Detach,然后再新线程中Attach
因为这个连个类和线程相关。


如果你要确实要跨线程操作,那你还是用winsock吧,直接API
fishion 2011-03-18
  • 打赏
  • 举报
回复
好像说CSocket不是线程安全的,所以跨线程操作可能有问题
可以用一般的winsock来编程,给线程传入创建的套节字
chenjiawei007 2011-03-18
  • 打赏
  • 举报
回复
m_sockSend 是 CServerDlg 的成员变量吗?

那你的线程中的m_sockSend 应该是无效的,通过类指针调用此成员变量即可。

奇怪,觉得应该编译不过啊。
KID_coder 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wmnmtm 的回复:]
如果在线程函数中声明对象呢,不是就不存在跨线程了吗

UINT ThreadFunc1(LPVOID lpParam)
{
CControlSocket m_sockSend;

if(m_sockSend.Create(8080,SOCK_DGRAM,NULL))//创建套接字
{
// pwwm->m_sockSend.Bind(8080,"127.0.0.1"); //绑定本……
[/Quote]
CAsyncSocket对象需要窗口支持
shenyi0106 2011-03-18
  • 打赏
  • 举报
回复
MFC分 用户界面线程 和 计算线程

用户界面线程 有消息泵,可以中转消息
计算线程没有消息泵

用户界面线程可以从CWinThread类派生一个出来,
计算线程就定义一个stdcall API函数就可以了(就是你用的方法)

CAsyncSocket内封装了一个CSockWnd窗口,用来中转消息,所以它和它的派生类都必须运行在有消息泵的线程中

由于CSocket的特殊封装,用它的阻塞模式可以直接应用于计算线程,但是重载模式也必须运行在用户界面线程中
shenyi0106 2011-03-18
  • 打赏
  • 举报
回复
CAsyncSocket依赖窗口句柄,因为它需要消息作为中转媒介

直接用CSocket可以

或者用winsock API

或者从重载CWinThread继承一个类,在里面写你的Create
wmnmtm 2011-03-18
  • 打赏
  • 举报
回复
如果在线程函数中声明对象呢,不是就不存在跨线程了吗

UINT ThreadFunc1(LPVOID lpParam)
{
CControlSocket m_sockSend;

if(m_sockSend.Create(8080,SOCK_DGRAM,NULL))//创建套接字
{
// pwwm->m_sockSend.Bind(8080,"127.0.0.1"); //绑定本地套接口
}
else
{
AfxMessageBox("Socket创建失败!");
}
但是,那句Create还是会出错,难道Create只能在主线程中用
KID_coder 2011-03-18
  • 打赏
  • 举报
回复
使用多线程时需要 Detach()分离,然后在新线程中Attac()附加SOCKET句柄~
查下msdn吧
wmnmtm 2011-03-18
  • 打赏
  • 举报
回复
UINT ThreadFunc1(LPVOID lpParam)
{
CServerDlg* pwwm=(CServerDlg*)lpParam;
pwwm->m_sockSend.Create(8081,SOCK_DGRAM,NULL);//这句有误,老提示内存不能为read

...
}

在pThread1=AfxBeginThread(ThreadFunc1,this); 时,把对话框的指针this传给线程函数了,m_sockSend为对话框的一个成员函数。CControlSocket m_sockSend;

而CControlSocket是派生而来,如下
class CControlSocket : public CAsyncSocket

wmnmtm 2011-03-18
  • 打赏
  • 举报
回复
正在试验各位说的,谢谢大家

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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