+ -
当前位置:首页 → 问答吧 → SOCKET线程卡死程序界面的问题?

SOCKET线程卡死程序界面的问题?

时间:2011-12-07

来源:互联网

直接上代码:
C/C++ code

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

    // TODO: Delete these three lines if you don't want the toolbar to
    //  be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    SetTimer(1,2000,NULL);   //启动线程

    return 0;
}


void CMainFrame::OnTimer(UINT nIDEvent) 
{
    // TODO: Add your message handler code here and/or call default
    CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
    CDemo1View *pView=(CDemo1View *)pMain->GetActiveView();

    #ifdef IEC_61850_USE
        if(pView->CreateIEC61850Socket() == FALSE)    //创建SOCKET线程并accept客户端的连接,当执行这里时,程序的整个框架就是卡死状态,但创建的SOCKET的线程工作正常!   
        {
            AfxMessageBox(_T("创建61850Socket失败!"));            
        }

    #endif
   
    CFrameWnd::OnTimer(nIDEvent);
}



线程工作正常,但ontimer开始执行后,框架就死了,请问怎么解决?成分感谢!

作者: piplu   发布时间: 2011-12-07

OnTimer里面就不用再调用OnTimer了,最后一行代码去掉

作者: wutaozhao   发布时间: 2011-12-07

引用 1 楼 wutaozhao 的回复:
OnTimer里面就不用再调用OnTimer了,最后一行代码去掉


已测试,不是这里的问题! BEBUG下去,是因为if(pView->CreateIEC61850Socket() == FALSE) 这句,这个SOCKET的线程会一直处于accept检测客户端的连接,也就是ONTIMER的代码没法执行完,倒置程序主界面卡死,我对THREAD编程不熟,麻烦大家请教。 万分感谢!

作者: piplu   发布时间: 2011-12-07

引用楼主 piplu 的回复:
直接上代码:
C/C++ code

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_F……


你这里用的是定时器,是由界面线程执行的。
创建线程用AfxBeginThread或CreateThread或_beginthreadex或_beginthread

作者: stjay   发布时间: 2011-12-07

OnTimer里面就不用再调用OnTimer了,最后一行代码去掉

属于基类的回调.

关键原因在于 ontimer并不是实现了多线程,仍在主线程中create

作者: yynetsdk   发布时间: 2011-12-07

现在问题就是我的SOCKET线程会一直在运行,因为一直要检测客户端的连接。 而启动这个线程我不知道挂在哪里。 我放在precreatwindows的系统函数里面的话,界面就显示不出来,反正是不能放在跟界面相关的函数里头,后面我就想到用ontimer来触发这个线程启动,但总是仍然还在。 只要ontimer的代码没执行完,主程序的界面还是会卡死,请问大家如何解决这个问题????

作者: piplu   发布时间: 2011-12-07

OnTime里不执行完成,程序是没有办法处理其它消息的。GetMessage里取出一条消息,然后借助Windows系统的User32.dll下发到窗口过程函数处理该消息,消息执行完成以后再取出下一条,依次进行。

你那个等待连接的操作可以放到一个单独的线程中去做

作者: VisualEleven   发布时间: 2011-12-07

我觉得你就没有启动线程,那把你启动线程的代码给出来,用多线程啊,不是用timer

作者: yayafu   发布时间: 2011-12-07

SetTimer是创建一个定时器,不是创建线程,创建线程应该用CreateThread 获得__beginthreadex
你用的SetTimer创建定时器后,Ontimer还是在和界面同一个线程中被调用,所以在Ontimer中调用Socket的accept函数就会把主界面线程阻塞了。
 所以改成用真正的创建线程函数创建线程

作者: zhaoze87   发布时间: 2011-12-07

引用 8 楼 zhaoze87 的回复:
SetTimer是创建一个定时器,不是创建线程,创建线程应该用CreateThread 获得__beginthreadex
你用的SetTimer创建定时器后,Ontimer还是在和界面同一个线程中被调用,所以在Ontimer中调用Socket的accept函数就会把主界面线程阻塞了。
所以改成用真正的创建线程函数创建线程


创建线程应该用CreateThread 或者__beginthreadex

作者: zhaoze87   发布时间: 2011-12-07

引用 1 楼 wutaozhao 的回复:

OnTimer里面就不用再调用OnTimer了,最后一行代码去掉

不好意思,看错了,可以将创建Socket操作单独放一个线程里,或者尝试采用异步socket

作者: wutaozhao   发布时间: 2011-12-07