应该可行的
给你个函数参考一下
void CSendView::OnConnect(WPARAM wparam, LPARAM lparam)
{
pFrame->m_wndStatusBar.SetPaneText(1,_T("客户机正在连接我端服务器..."));
//响应客户连接
SOCKET sServer=(SOCKET)wparam;
int nErrorCode = HIWORD(lparam);
int nMessage = LOWORD(lparam);
int nLength = sizeof(SOCKADDR_IN);
SOCKADDR_IN Client_Addr;
int nIndex;
CString m_Err_Message;
CConnect *pClient=new CConnect;
//保存客户机连接信息
nIndex=m_Connect.Add(pClient);
pClient->m_Connect=accept(sServer,(LPSOCKADDR)&Client_Addr,&nLength);
if(pClient->m_Connect==INVALID_SOCKET)
{
m_Err_Message.Format("错误:无法接受客户机连接SOCKET!,\n错误码:",WSAGetLastError());
AfxMessageBox(m_Err_Message);
m_Connect.RemoveAt(nIndex);
return ;
}
pClient->m_Address=inet_ntoa(Client_Addr.sin_addr);
//进行消息队列循环
::WSAAsyncSelect(pClient->m_Connect,m_hWnd,WM_SOCKET_READ,FD_READ|FD_CLOSE);
//创建连接客户端的子线程
pClient->m_Client=new CClientThread(GetSafeHwnd(),pClient->m_Connect,pClient->m_Address);
if( pClient->m_Client== NULL )
{
::MessageBox(GetSafeHwnd(),"无法创建连接子线程", "错误", MB_OK|MB_ICONSTOP );
return ;
}
pClient->m_Client->CreateThread();
pFrame->m_wndStatusBar.SetPaneText(1,_T("连接完毕..."));
if(!App.Gl_Begin)
pClient->m_Client->PostThreadMessage(WM_SOCKET_SEND_DATA,(WPARAM)ReturnMessage(),0L);
}其中CServerThread、CClientThread都是由CWinThread继承的,你先参考一下,有问题[email protected],一同研究

解决方案 »

  1.   

    我手上有个例子,有兴趣要源代码留下E-mail.
      

  2.   

    干脆我还是贴我的代码吧!哪位有时间的帮我看看:
    BOOL CTryDlg::OnInitDialog()
    {
    CDialog::OnInitDialog();
             m_pThread = AfxBeginThread((AFX_THREADPROC)ThrdFunc,(LPVOID)this); return TRUE;  
    }UINT ThrdFunc(LPVOID pParam)
    {
    CTryDlg* pDlg = (CTryDlg*)pParam; pDlg->m_pSocket = new CMySocket();
    if(!pDlg->m_pSocket->Create())
    {
    delete pDlg->m_pSocket;
    AfxMessageBox("ERROR!");
    }
    return 0L;
    }
    其中m_pSocket是CTryDlg的puclic成员,类型CMysocket*;
    m_pThread同上,类型CWinThread*;CMySocket由CSocket派生。
      

  3.   

    不知道算不算微软的bug,用静态连接就会出现你那样的错误,用动态连接就没事!
    你还是用动态连接吧!要不就直接用API。
      

  4.   

    哦?不过我用的就是动态连接。
    实际上我的m_psocket在线程外也要用,
    否则我根本就不会这样写——直接在线程
    里定义套接字就完了。
      

  5.   

    你在线程间传递mfc对象,这是一个典型的错误。
    你应该传递这个句柄hSocket,然后用detach()和attach(),
    来重新构造一个CSocket对象。
    微软的CAsyncSocket有很多问题的,我也出过不少问题了,
    建议你看看这个类的实现代码,就明白这些问题的根源了。
      

  6.   

    哦哦哦哦,想起来了。不过一直都没在意
    这问题,以前也见过类似的文档,
    总算有人说到点上了。
    照begin你的意思,是要在线程外建立socket,
    然后传句柄进去。麻烦你给点代码瞻仰瞻仰,谢过!
      

  7.   

    实际上就是多线程间共享一个Socket的问题。
    好了,差不多了。
      

  8.   

    这种问题的提出应该有一个前提.
    一.服务器程序.
    二.客户端程序.
    作为服务器程序很少用CSocket的什么,用什么连接池,请求池,线程池.
    客户端还可以考虑.可以直接用一个线程驱动CSocket.这样可以实现异步连接.
                    将整个系统的数据交互集中在一起作,有理于模块独立.
                     
      

  9.   

    是吗?因为我的程序比较简单。发送倒是小事,不过我要流控。
    xmake,你说的连接池,请求池,线程池可以去什么地方看看?
      

  10.   

    呵呵,你好好研究一下CASYNCSOCKET吧,微软就是坏,它在类的封装时,起了一个线程,我费了九牛二虎之力才搞明白。今天就无偿给你这个信息吧。你必须先起一个线程,在线程里面CREATE。明白否?
      

  11.   

    关键是M$把SOCKET绑到了一个窗口上,用工作者线程就有问题了。
      

  12.   

    to xmake.
       连接池,请求池,线程池只有win2000才能用吧.
      

  13.   

    好像还是有问题?
    UINT SendData(LPVOID Param)
    {
        CXXXDlg* pDlg = (CXXXDlg*)Param;
        ...
        CSocket* pSocket = new CSocket();
        pSocket->Attach(pdlg->m_pSocket->m_hSocket);
        pSocket->Create();
    }
    惨得很,还是错了,怎么回事?
      

  14.   

    应该如下  
    CSocket* pSocket = new CSocket();
      pDlg->m_pSocket=new CSocket();
      pSocket->Create();
      pDlg->m_pSocket->Attach(pSocket->m_hSocket);
      

  15.   

    楼上老兄,问题依旧,还是
    CMapPtrToPtr::GetValueAt(void* key) const
    中的m_pHashTable错误。
      

  16.   

    可以用,WINSOCK 2。0,API做出来在进程中新建,SOCKET,
      

  17.   

    刚才把有关的帖子看了一遍,总算搞定乐。
    m_pclitSocket->Detach();
    在线程函数的入口加乐AfxSockInit()就好了。
    不过具体原因还是不太懂,在请指点一下?
    下次还是用WinSock API吧。
      

  18.   

    本人很菜,写出的程序不好看还请大家多多指点
    这个一个IE控件程序SOCK通信进程序是用来做口令验证用的
    我的QQ是1271891
    请多多指点 SOCKET   wsSock,temp;
    CString str[3],wangdian;
    char szhostname[128];
    int i,iph=0; str[iph]="";
    if( gethostname(szhostname, 128) == 0 )
    {
    // get host adresses
    struct hostent * phost;

      CString addr;

    phost = gethostbyname(szhostname);
     int j;
    for( i = 0; phost!= NULL && phost->h_addr_list[i]!= NULL; i++ )
      {
      for( j = 0; j!=4; j++ )
      {
     
      if( j > 0 )
      str[i] += ".";
    addr.Format("%u", (unsigned int)((unsigned
      char*)phost->h_addr_list[i])[j]);
    str[i] += addr;
      }
       // str now contains one local ip address - do whatever you want to do with it (probably add it to a list)
      }
    }
    //STR 出来是本地的IP ,可以有多个IP
    //szhostname,本地电脑的名子
    if(i!=1)iph=0;
    struct sockaddr_in clhere;wsSock= socket( AF_INET, SOCK_STREAM, 0);
    if (wsSock == INVALID_SOCKET) 
    {
    closesocket(wsSock);
    return false;
    }//给全部本地IP,套接
    clhere.sin_family=AF_INET;
    clhere.sin_addr.s_addr=inet_addr(LPCTSTR(str[iph]));
    //here.sin_addr.s_addr=inet_addr("192.168.0.1");
    clhere.sin_port=htons(7711); if(bind(wsSock,(LPSOCKADDR)&clhere,sizeof(clhere)))
    {
    // MessageBox(m_hwndIE,"接收套接字绑定失败!","",MB_OK); }
    int fromlen = sizeof(clhere); struct sockaddr_in here;
    here.sin_family=AF_INET;
    here.sin_addr.s_addr=inet_addr("192.168.0.1");
    here.sin_port=htons(5816);int status= sizeof(here); 
     //调用阻塞函数accept,一直到远端响应为止listen(wsSock,5);
    while(1)
    {
    temp = accept( wsSock,(struct sockaddr*)&here,&status);
    closesocket(temp);
    }
      

  19.   

    AfxSockInit()
    这个也要用的不知到为什么请高手指点
      

  20.   

    #ifndef _AFXDLL
    // 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
      

  21.   

    上面的内容节选自下面的函数:BOOL AFXAPI AfxSocketInit(WSADATA* lpwsaData)使用动态连接时,如果不调用AfxSocketInit,问题就出现了。
      

  22.   

    用socket API,that's easy!我就喜欢在线程里用socket...
      

  23.   

    节选自Visual Studio Service Pack Readme
    Service Pack 3 更正的错误:
    下列 MFC 问题已经被更正:MFC 6.0 可以使用 Microsoft(R) Access 2000 数据库。若要在应用程序中使用此功能,必须使用下例方法启用 DAO 3.6: 
    在进行任何与数据库相关的调用前,链接 DLL 版的 MFC,并将下列行添至 InitInstance 中:
    AfxGetModuleState()->m_dwVersion = 0x0601
    在 _MFC_VER 设置为 0x0601 后重新编译 MFC 静态库。 
    对于未使用文档/视图结构的 SDI 应用程序,MFC AppWizard 为工具栏按钮关联了不正确的图像。 
    在多线程的静态链接 MFC 应用程序中,套接字线程的状态未被初始化。如果应用程序中的某一线程调用了 AfxSocketInit,那么再从其他线程中进一步地调用该相同函数时,将不能为该线程设置套接字线程的状态。 
    ……
      

  24.   

    在线程中创建CSocket的问题解决了吗?如果解决了的话,给我看看好吗?
      

  25.   

    jiangsheng,我用的是SP5,而且是动态链接。
    zhangzq71,简单的描述如下:
    UINT SendData(LPVOID Param)
    {
        CXXXDlg* pDlg = (CXXXDlg*)Param;
        ...
        AfxSockInit();
        CSocket* pSocket = new CSocket();
        pSocket->FromHandle(pDlg->m_pSocket->m_hSocket);
        pSocket->Create();
        ...
        delete pSocket;
        
        return 0L;
    }
      

  26.   

    zhaoweidf(zw.ln)的建议非常好,我已经试过了
    我天天用她
    还有个头文件Afxsock.h
      

  27.   

    BOOL CClientThread::InitInstance()
    {
    // TODO:  perform and per-thread initialization here
    CSocketThreadBase ::InitInstance();
    TimeSetEvent();
    m_pSocket = new CClientSocket(this);
    m_pSocket->Attach(m_hClientSocket);
    ASSERT_VALID(m_pSocket);
    m_pSocket->CreatePointer();
    m_eventSocketConnected.SetEvent();
    TRACE("CClientThread: connected");
    return TRUE;
    }
    CClientThread::CClientThread(CListeningThread *pListeningThread,SOCKET hClientSocket)
    {
    m_pSocket=NULL;
    m_hClientSocket=hClientSocket;
    m_pListeningThread=pListeningThread;
    }
    void CListeningThread::OnCreateSocket(WPARAM wParam, LPARAM lParam)
    {
    m_pListeningSocket = new CListeningSocket(this);
    if (m_pListeningSocket->Create(g_SocketOption.nPort))
    {
    if (m_pListeningSocket->Listen()) {
    g_ClientCount=0;
    return ;
    }
    }
    delete m_pListeningSocket;
    m_pListeningSocket = NULL;
    }
      

  28.   

    我初学Internet编程,我想老手对线程类东西一定很熟了吧,有个问题,CreateThread和派生CWinThread创建的线程是不是一个不能维持消息队列一个能呢?还有CSocket如果在一个用CreateThread创建的线程(假定这个线程不能维持一个消息队列,只是执行完指定函数就结束线程),而CSocket对象发出了消息,是不是可能导致错误?
    以上都是假定,嘻嘻~
      

  29.   

    如果要在 线程中使用一个已经打开的SOCKET
    CMyDialog::CDialog
    {
    CServerPocess *pServer;
    }
    在global建立线程函数
    {
    CMyDialog* serverdlg=(CMyDialog*)theApp.m_pMainWnd;
    CServerPocess* server = serverdlg->pServer;
    }
    CServerPocess是我封装的一个Socket类
    得到了SOCKET,然后随便做什么了!
      

  30.   

    MFC中SOCKET有异步的,通过NEW来动态创建,不需要内在使用线程!!
      

  31.   

    多线程SOCKET最好不要用 MFC CSocket/CAsyncSocket。1、这两个类中有窗口Message Loop。这个Message Loop只能在一个线程中有作用。一有消息要PumpMessage,而这个PumpMessage调用不在那个线程中,就会出exception。2、内部有一个链表,在很多SOCKET操作时会更新此链表。多线程存取修改同一个链表也会出问题的。3、CSocket/CAsyncSocket都是异步的。CSocket是是表现的象是同步的而已。一个线程处理SOCKET一般就足够用了。没必要用多线程时就不要用。我的多线程SOCKET处理是用Win Socket API直接做的,SOCKET建立后为相应的SOCKET启动一个处理线程。SOCKET关闭后结束此线程。我在多线程中使用MFC 的CSocket/CAsyncSocket类时把PumpMessage问题、链表问题都绕过去了,但那实际上和普通的直接用 API 做的没什么区别了。也就是说:多线程SOCKET不要用MFC 的 SOCKET处理。
      

  32.   

    在JAVA中是可以的,同一台机器同一个端口,可以开多个线程,在每个线程中申请SOCKET,然后发信
    ,发信完关闭.