我用MySocket->Send消息,怎么接收消息,触发OnReceive还是Receive来接受消息,?
有人说可以对CSocket设置同步异步,在那设置的?
具体的:
    点击Login按钮Send(),跟踪SEND _SUCCESS后再没有响应,求救!

解决方案 »

  1.   

    CSocket本身是一个同步socket,没有必要使用异步方式.
    OnReceive是callback函数,不是用户函数,因此,你是不能直接调用的.
    你需要使用Receive来接收消息,但是,对于同步处理方式,在接受到消息之前,函数是不能够返回的,这就是为什么存在OnReceive的道理,当系统调用OnReceive的时候,标示有消息到达,在此时,你再调用Receive就好了!
      

  2.   

    //服务器线程
    UINT thread(LPVOID p)
    {
    char buff[100];
    CSize size;
    size.cx=0;
    size.cy=30;
    int s=1,msgcount,loop=1,flag=0;
    CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
    //获得客户端数量
    msgcount=dlg->getcount();
    if (msgcount==-1)
    loop=0;
    if(loop)
    {
    s=1;
    dlg->msgsock[msgcount]=accept(dlg->sock,(sockaddr*)&(dlg->serv),&(dlg->addlen));
    if (dlg->msgsock[msgcount]==INVALID_SOCKET)
    {
    dlg->m_edit.SetWindowText("Error accept");
    }
    else
    {
    //启动线程
    AfxBeginThread(thread,0);
    dlg->SetForegroundWindow();
    dlg->m_list.InsertItem(dlg->count++,"连接成功");
    dlg->m_list.InsertItem(dlg->count++,inet_ntoa(dlg->serv.sin_addr));
    dlg->m_list.Scroll(size);
    dlg->m_button.EnableWindow(TRUE);
    while(s!=SOCKET_ERROR)
    {
    //循环接收数据
    s=recv(dlg->msgsock[msgcount],buff,100,0);
    dlg->SetForegroundWindow();
    if (s!=SOCKET_ERROR)
    {
    dlg->m_list.InsertItem(dlg->count++,buff);
    dlg->m_list.Scroll(size);
    dlg->sendtoall(dlg->msgsock[msgcount],buff);
    }
    } send(dlg->msgsock[msgcount],"Disconnected",100,0);
    dlg->m_list.InsertItem(dlg->count++,"Disconnected");
    dlg->m_list.Scroll(size);
    dlg->msgsock[msgcount]=NULL;
    for (int i=0;i<50;i++)
    if (dlg->msgsock[i]!=NULL)
    flag=1;
    if (flag!=1)
    dlg->m_button.EnableWindow(FALSE);
    closesocket(dlg->msgsock[msgcount]);

    }
    }
    //终止线程
    AfxEndThread(0);
    return 0;
    }
      

  3.   

    奇怪的是我在发消息后,并没有跟踪到OnReceive函数中,请说具体一点,谢谢!
    比如说说:CScoket从创建到收发消息的整个调用函数的流程。
     因为这是一个较简单的基对话框的客户端模拟器。
      

  4.   

    初始化:
    m_socket.SetRemoteHost (m_host);
    m_socket.SetRemotePort (7000);vtHost.bstrVal = m_host.AllocSysString ();
    vtPort.bstrVal = m_port.AllocSysString ();
    m_socket.Connect (vtHost,vtPort);
    //已经连接
    m_socket.SendData (vtCommand);//发送然后在OnDataArrivalWinsock1函数中使用
    m_socket.GetData(&vtData,vtType,vtMaxlen);
      

  5.   

    用SDK写的SOCKET,我感觉更快!
    void CSupplyView::OnStartsupply() 
    {
    // TODO: Add your command handler code here
    if (m_bflag)
    {
    MessageBox("代理已经启用!","Supply-代理",MB_OK|MB_ICONINFORMATION);
    return;
    } m_nMode=1;
    m_bflag=TRUE;
    m_bT2C=TRUE;
    m_bC2T=TRUE; CString sfile("IniSupply.ini");
    CStdioFile inifile;
    if (!inifile.Open(sfile,CFile::modeRead))
    {
    MessageBox("打开初始配置文件失败!","Supply-代理",MB_OK|MB_ICONINFORMATION);
    return;
    }
    m_sfilepath=inifile.GetFilePath(); 
        inifile.Close();
    m_hadS = NULL ;
    m_hadC = NULL ;
    m_BList = 2; g_MainView = this ;
    WORD wVersionRequested;
        WSADATA wsaData;
    CString csError;
    csError.LoadString(IDS_STRINGERROR);  memset(m_csOutIp,'\0',sizeof(m_csOutIp));  
    memset(m_csLocalIP,'\0',sizeof(m_csLocalIP)); csError = csError + ".....系统退出!";

        int err;
     
        wVersionRequested = MAKEWORD( 2, 2 );
     
        err = WSAStartup( wVersionRequested, &wsaData );
        if ( err != 0 ) 
    {
            /* Tell the user that we could not find a usable */
            /* WinSock DLL.          */
    MessageBox(csError);
    exit(0);        
    }
     
        /* Confirm that the WinSock DLL supports 2.2.*/
        /* Note that if the DLL supports versions greater    */
        /* than 2.2 in addition to 2.2, it will still return */
        /* 2.2 in wVersion since that is the version we      */
        /* requested.                                        */
     
       if ( LOBYTE( wsaData.wVersion ) != 2 ||
            HIBYTE( wsaData.wVersion ) != 2 ) 
       {
           /* Tell the user that we could not find a usable */
           /* WinSock DLL.                                  */
           WSACleanup();
       csError.LoadString(IDS_STRINNETDLLERROR); 
       MessageBox(csError,"Supply-代理",MB_OK|MB_ICONINFORMATION);
       exit(0);        
           return; 
       }      err =  GetPrivateProfileString("base" ,"outIp","127.0.0.1",m_csOutIp,sizeof(m_csLocalIP),m_sfilepath);
       err =  GetPrivateProfileString("base" ,"LocalIP","127.0.0.1",m_csLocalIP,sizeof(m_csLocalIP),m_sfilepath);   m_loutport = GetPrivateProfileInt("base","outport",444,m_sfilepath);
       m_lLocalport = GetPrivateProfileInt("base","Localport",444,m_sfilepath);                      m_hadMain  =  CreateThread(NULL,0,LPTHREAD_START_ROUTINE(ThreadFuncSocketList),(void *)this,0,NULL);                  //////////记录/////////
       g_MainView->Message("启动代理!","成功","本地");
    }DWORD WINAPI ThreadFuncSocketList( LPVOID lpParam ) 
    {     
    CSupplyView *pView = (CSupplyView *)lpParam;

    //////////记录/////////
        g_MainView->Message("辅助控制线程创建","成功","本地");

    if (-1==pView->InitSocktList())
    {
    AfxMessageBox("由于本地套接字原因,代理被禁用!",MB_OK|MB_ICONINFORMATION);
    g_MainView->m_nMode=0;
    g_MainView->Message("代理被禁用!","成功","本地");
    return -1;
    }
    //AfxMessageBox("启动代理!",MB_OK|MB_ICONINFORMATION);
        return 0; 

      

  6.   

    void CSupplyView::OnStopsupply() 
    {
    // TODO: Add your command handler code here
    m_nMode=0;

    if (!m_bflag)
    {
    MessageBox("没有启用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
    return;
    }

    m_bT2C=FALSE;
    m_bC2T=FALSE; Sleep(1); CloseHandle(m_hadMain);
    closesocket(m_SockList); CloseHandle(m_hadS);
    CloseHandle(m_hadC);
        
    if (m_SockConn != 0)
    {

    closesocket(m_SockConn);
    }
    m_bflag=FALSE;
    }void CSupplyView::OnUpdateStartsupply(CCmdUI* pCmdUI) 
    {
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(1==m_nMode);
    }void CSupplyView::OnUpdateStopsupply(CCmdUI* pCmdUI) 
    {
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(0==m_nMode);
    }void CSupplyView::OnConfig() 
    {
    // TODO: Add your command handler code here
        CString sfile("temporary.ini");
    CStdioFile inifile;
    if (!inifile.Open(sfile,CFile::modeWrite|CFile::typeText))
    {
    if (!inifile.Open(sfile,CFile::modeCreate|CFile::modeWrite|CFile::typeText))
    {
    AfxMessageBox("创建初始配置文件失败!");
    return;
    }
    }
    inifile.SeekToBegin();
    CConfigDlg dlg;
    if (dlg.DoModal()==IDOK)
    {
    inifile.WriteString("[base]\n");
    inifile.WriteString("outIp=");
    inifile.WriteString(dlg.m_soutip);
    inifile.WriteString("\n");
    inifile.WriteString("outport=");
    inifile.WriteString(dlg.m_soutport);
    inifile.WriteString("\n");
    inifile.WriteString("Localport=");
    inifile.WriteString(dlg.m_slocalport);
    inifile.WriteString("\n");
    inifile.WriteString("LocalIP=");
    inifile.WriteString(dlg.m_slocalip);
    inifile.WriteString("\n");
    inifile.Flush();
    inifile.Close();
    CFile::Remove("IniSupply.ini");
            inifile.Rename(sfile,"IniSupply.ini");
    }
    else
    {
    inifile.Close();
    CFile::Remove(sfile);
    }
    }
    /////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    BOOL CSupplyView::InitSocktList()
    {
    m_SockList = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);    if(m_SockList ==INVALID_SOCKET)
    {
     MessageBox("\nsocket() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
     return -1;      
    }    m_sadLocal.sin_addr.s_addr=htonl(INADDR_ANY);
        m_sadLocal.sin_family=AF_INET;
        m_sadLocal.sin_port=htons((unsigned short)m_lLocalport); if(bind(m_SockList,(struct sockaddr *)&m_sadLocal,sizeof(m_sadLocal))==SOCKET_ERROR)
       {
          MessageBox("\nbind() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
      return -1;      
          
       }
       
        //////////记录/////////
        Message("创建本地套接字及绑定端口号","成功","本地");   SockList();
       return 0;
    }BOOL CSupplyView:: ConnectToServier()
    {
    long lError;    m_SockConn = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);    if( m_SockConn ==INVALID_SOCKET)
    {         
     MessageBox("\nsocket() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
     return -1;      
    } m_sadRome.sin_addr.S_un.S_addr = inet_addr(m_csOutIp);
        m_sadRome.sin_family=AF_INET;        
    m_sadRome.sin_port=htons((unsigned short)m_loutport);    //////////记录/////////
        g_MainView->Message("创建新套接字","成功","本地"); lError = connect(m_SockConn,(const struct sockaddr *)&m_sadRome,sizeof(m_sadRome));      if (lError != 0)
    {
        return -1 ; 
    }    //////////记录/////////
        g_MainView->Message("此套接字与服务器建立连接","成功","服务器--本地");

        return TRUE;
    }void CSupplyView::SockList()
    {
         int iAddrSize; 
         struct sockaddr Slave;    if ( m_BList != 2)
     {
     return ;
     }
     m_BList = TRUE ;  if ((!g_MainView->m_bC2T)||(!g_MainView->m_bT2C))
     {
     Message("强制禁用代理!","成功","本地");
     MessageBox("强制禁用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
     return;
     }  closesocket(m_SockConn);
     
     closesocket(m_SockNew);

        if (m_hadS != NULL)
    {
           CloseHandle(m_hadS);
       m_hadS = NULL;
    }     if (m_hadC != NULL)
    {
           CloseHandle(m_hadC);
       m_hadC = NULL ;
    }     iAddrSize=sizeof(Slave);  if(listen(m_SockList,1)==SOCKET_ERROR)
     {
            MessageBox("\nlisten() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);      
     }     //////////记录/////////
         Message("本地套接字启动监听","成功","本地");
     int i=0;
     while(i<=5)
     {     m_SockNew = accept(m_SockList,(struct sockaddr *)&Slave,&iAddrSize);
         if(m_SockNew == INVALID_SOCKET)
     {
     if ((!g_MainView->m_bC2T)||(!g_MainView->m_bT2C))
     {
     Message("强制禁用代理!","成功","本地");
         MessageBox("强制禁用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
         return;
     }
             MessageBox("\naccept() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
     }
     else
     {
     //////////记录/////////
             Message("通过本地套接字的接收,建立与CLIENT连接的新的套接字","成功","本地--客户端");
         
     if (ConnectToServier() == TRUE )
     {   
      m_SockArray1[0] = m_SockNew;
      m_SockArray1[1] = m_SockConn;      DWORD dwThreadID ,dwThreadID1;   
      
      m_hadS = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(TCPDataC2T),(LPVOID)&m_SockArray1[0],0,&dwThreadID);   
      
                  Message("建立数据传输通道(客户端-->本地-->服务器)的辅助线程创建","成功","通道");   m_hadC = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(TCPDataT2C),(LPVOID)&m_SockArray1[0],0,&dwThreadID1);      Message("建立数据传输通道(服务器-->本地-->客户端)的辅助线程创建","成功","通道");
      }
     else
     {
     Message("代理被禁用!","成功","本地");
         MessageBox("新套接字有错误,代理被禁用!","Supply-代理",MB_OK|MB_ICONINFORMATION);
     }
      }
     }
     m_BList = 0;
    }#define BuffSize 80*1024 //缓冲区大小20k
      

  7.   

    DWORD WINAPI TCPDataT2C(SOCKET* sock)

          int iRet,
          ret=-1,//select 返回值      iSTCBCS=0;//STCBCS=SendToClientBuffCurrentSize
          char szRecvFromTargetBuff[BuffSize]={0},
          szSendToClientBuff[BuffSize]={0};
          fd_set fdread,fdwrite;      while(1)
      {
             FD_ZERO(&fdread);
             FD_ZERO(&fdwrite);
             FD_SET(sock[0],&fdwrite);
             FD_SET(sock[1],&fdread);
             if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
    {
                TRACE1("\n [服务器]select() failed:%d",GetLastError());
                break;
    }        if(ret>0)
    {
                 //sTarget可读,从target接收数据
                 if(FD_ISSET(sock[1],&fdread))
     {
                     //接收target返回数据
                     iRet=recv(sock[1],szRecvFromTargetBuff,BuffSize,0);
                     if(iRet==SOCKET_ERROR)
     {
                          TRACE1("\n [服务器]recv() from target failed:%d",GetLastError());   
                          break;
     }
                     else if(iRet==0)
                          break;                 g_MainView->Message("接收从服务器发送来的数据","成功","服务器-->本地");
     //数据的认证过程,取得各种所需的数据,比较业务流水号的正确性
     iRet=send(sock[0],szRecvFromTargetBuff,iRet,0);  if(iRet==SOCKET_ERROR)
     {
                          TRACE1("\n [服务器]recv() from target failed:%d",GetLastError());   
                          break;
     }                 g_MainView->Message("接收的数据从本地发往客户端","成功","本地-->客户端");
     
    //  afxDump << "[服务器]收到的字符串" <<  szRecvFromTargetBuff << "一共有 ="<< iRet << "\n" ;                 //清空接收target返回数据缓冲区
                     memset(szRecvFromTargetBuff,'\0',BuffSize);
                     //刷新发送到client的数据缓冲区当前大小
                     iSTCBCS+=iRet;
     }
    }//end of select ret
            Sleep(1);
     }//end of while    
     g_MainView->NewSockList(); 
         return 0;
    } //此函数负责从Client读取数据,然后转发给Target
    DWORD WINAPI TCPDataC2T(SOCKET* sock)

         int iRet,
         ret=-1,//select 返回值
         iSTTBCS=0;//STTBCS=SendToTargetBuffCurrentSize
         char szSendToTargetBuff[BuffSize]={0},
         szRecvFromClientBuff[BuffSize]={0};
         fd_set fdread,fdwrite;     
         while(1)
     { 
            FD_ZERO(&fdread);
            FD_ZERO(&fdwrite);
            FD_SET(sock[0],&fdread);
            FD_SET(sock[1],&fdwrite);
            if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
    {
               TRACE1("\n[客户端]select() failed:%d",GetLastError());
               break;
    }
             if(ret>0)
    {
                //sClinet可读,client有数据要发送过来
                if(FD_ISSET(sock[0],&fdread))
    {
                    //接收sock[0]发送来的数据
                    iRet=recv(sock[0],szRecvFromClientBuff,BuffSize -1 ,0);                if(iRet==SOCKET_ERROR)
    {
                        TRACE1("\n[客户端]recv() from sock[0] failed:%d",GetLastError());
                        break;
    }
                    else if(iRet==0)
                        break;
                    //此处需要处理获得时间,业务流水号,判断数据是否超过1400
    //组包发送到防火墙代理模块
    g_MainView->Message("接收从客户端发送过来的数据","成功","客户端-->本地");

    iRet=send(sock[1],szRecvFromClientBuff,iRet,0); if (iRet == SOCKET_ERROR)
    {
       break ;
    } g_MainView->Message("接收的数据从本地发往服务器","成功","本地-->服务器");
      
    // afxDump << "[客户端]收到的字符串" <<  szRecvFromClientBuff << "一共有 ="<< iRet << "\n" ;                //清空接收client数据的缓冲区
                    memset(szRecvFromClientBuff,'\0',BuffSize);
    }
          
    }//end of select ret 
            Sleep(1);
     }//end of data send & recv循环  
     g_MainView->NewSockList(); 
         return 0;
    }void CSupplyView::NewSockList()
    {
    //    afxDump << "进入新的NewSockList()\n";
    {
    m_BList ++ ;
        SockList();
    }
    }void CSupplyView::Message(char *cmd, char *result,char *ADDRESS)
    {
    CListCtrl& mess=GetListCtrl();
    int messcount=mess.GetItemCount();
    if(messcount>2000)
    mess.DeleteAllItems();
    else
    {
    CString a;
    int insertindex;
    insertindex=mess.InsertItem(0,result);
    mess.SetItem(insertindex,1,LVIF_TEXT,cmd,0,0,0,NULL);
    mess.SetItem(insertindex,2,LVIF_TEXT,ADDRESS,0,0,0,NULL);
    CTime t = CTime::GetCurrentTime();
    a=t.Format("%Y-%m-%d %H:%M:%S");
    mess.SetItem(insertindex,3,LVIF_TEXT,a,0,0,0,NULL);
    }
    }
    这是我写的代理部分,我想对你有帮助的!
      

  8.   

    还是不能明白!!!
    我发现不能进到OnReceive函数,到直接进入了OnClose了,为什么?
      

  9.   

    现在这个原因是服务端端掉了,发送一个断连消息,进入到Onclose函数。
    不过还是要谢谢各位:分照加