大家有没有遇到下面这种情况
从CSocket类继承CSocketClient,CSocketListen。其中CSocketListen响应OnAcceptCSocketServer中包含CSocketListen成员,CSocketClient链表,管理客户端连接。测试时,端口能正常打开。用网络调试助手也能连到服务端口上,用netstat 可以查到Established
但就没进入到OnAccept函数里。

解决方案 »

  1.   

    代码如下:
    #if !defined(AFX_SOCKETEX_H__F652EE22_2A40_4EE6_8F0E_7EA5EEB18A69__INCLUDED_)
    #define AFX_SOCKETEX_H__F652EE22_2A40_4EE6_8F0E_7EA5EEB18A69__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // SocketEx.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // CSocketClient command target
    class CSocketServer;class CSocketClient : public CAsyncSocket
    {
    // Attributes
    public:
    CSocketServer *m_pServer;
    CString m_csPeerAddr;
    UINT    m_nPeerPort; int m_nRecvHeartTimes;
    CString m_sRemoteTerminalAddr;
    CRITICAL_SECTION   AccessingEvent;
    BOOL m_bClientServer;
    int SendToClient(BYTE *pRecData, int nLen,BYTE pErCode);

    UINT m_nDelayToDel;

    int m_nRecPtr;//当前接收指针 piano 050321

    int m_nDealPtr;//当前处理指针 piano 050321
    int m_nDeal102Ptr;
    int m_nDealZhgPtr; int ReadData(BYTE *pBuf,int nLen);
    int m_nSignalIntensity;
    //BOOL IsLoginMessage();
    void OnRecived(BYTE* pRecBuf,int nLen);
    int SendData(BYTE* pSendBuf,int nLen);
    BYTE *m_pRecBuffer;
    HANDLE m_hRecBuffer; BOOL m_bNeedDelete;
    int m_nOldUse;
    int m_nCurUse;
    int m_nNumber;

    // Operations
    public:
    CSocketClient();
    CSocketClient(CSocketServer *pServer);
    virtual ~CSocketClient();// Overrides
    public:
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CSocketClient)
    public:
    virtual void OnReceive(int nErrorCode);
    virtual void OnSend(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    //}}AFX_VIRTUAL // Generated message map functions
    //{{AFX_MSG(CSocketClient)
    // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG// Implementation
    protected:
    };
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // CSocketListen command targetclass CSocketListen : public CAsyncSocket
    {
    // Attributes
    public: CSocketServer *m_pServer;
    //CTest55Dlg * hWnd;
    // Operations
    public:
    CSocketListen(CSocketServer *pServer);
    virtual ~CSocketListen();// Overrides
    public:
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CSocketListen)
    public:
    virtual void OnAccept(int nErrorCode);
    //}}AFX_VIRTUAL // Generated message map functions
    //{{AFX_MSG(CSocketListen)
    //}}AFX_MSG// Implementation
    protected:
    };
    class CSocketServer:public CObject
    {
    public:
    CSocketServer(char* IODiscribe); //设备地址

    // Attributes
    public:
    CString m_csName;
    CSocketListen *m_pListenSocket;
    CObList m_connectionList;
    CRITICAL_SECTION   AccessingEvent; BOOL m_bClientServer;// Operations
    public:
    //CSocketClient* GetConnectByTerminalAddr(CString sRemoteTerminalAddr);
    void MaintainLink();
    void CloseAllClient();
    void CloseClient(CSocketClient *pSocket);
    void ProcessPendingAccept();
    virtual ~CSocketServer();
    };/////////////////////////////////////////////////////////////////////////////
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_SOCKETEX_H__F652EE22_2A40_4EE6_8F0E_7EA5EEB18A69__INCLUDED_)
      

  2.   

    // SocketEx.cpp : implementation file
    //#include "stdafx.h"
    #include "test55.h"
    #include "SocketEx.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CSocketClient
    class CSocketServer;CSocketClient::CSocketClient()
    {
    }CSocketClient::CSocketClient(CSocketServer *pServer)
    {
    m_nSignalIntensity=-1;
    m_pServer = pServer;
    m_hRecBuffer = NULL;
    m_pRecBuffer = NULL;
    m_nCurUse = m_nOldUse = m_nNumber= 0; m_nRecPtr=0;
    m_nDealPtr=0; m_nDelayToDel=0;
    m_bNeedDelete=FALSE; InitializeCriticalSection(&AccessingEvent);
    m_hRecBuffer = GlobalAlloc(GPTR,sizeof(BYTE)*_max_recive_lentgh);
    if(m_hRecBuffer)
    {
    m_pRecBuffer = (BYTE *)GlobalLock(m_hRecBuffer);
    if(m_pRecBuffer == NULL)
    {
    GlobalFree(m_hRecBuffer);
    m_hRecBuffer = NULL;
    }
    }
    }CSocketClient::~CSocketClient()
    {
    EnterCriticalSection(&AccessingEvent);
    m_nRecPtr=0;
    m_nDealPtr=0;
    if(m_hRecBuffer)
    {
    GlobalUnlock(m_hRecBuffer);
    GlobalFree(m_hRecBuffer);
    }
    m_hRecBuffer=NULL;
    m_pRecBuffer=NULL;
    m_nRecPtr=0;
    LeaveCriticalSection(&AccessingEvent);
    DeleteCriticalSection(&AccessingEvent);
    }
    // Do not edit the following lines, which are needed by ClassWizard.
    #if 0
    BEGIN_MESSAGE_MAP(CSocketClient, CSocket)
    //{{AFX_MSG_MAP(CSocketClient)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    #endif // 0/////////////////////////////////////////////////////////////////////////////
    // CSocketClient member functionsvoid CSocketClient::OnReceive(int nErrorCode) 
    {
    // TODO: Add your specialized code here and/or call the base class

    CAsyncSocket::OnReceive(nErrorCode);
    }void CSocketClient::OnSend(int nErrorCode) 
    {
    // TODO: Add your specialized code here and/or call the base class

    CAsyncSocket::OnSend(nErrorCode);
    }void CSocketClient::OnClose(int nErrorCode) 
    {
    // TODO: Add your specialized code here and/or call the base class

    CAsyncSocket::OnClose(nErrorCode);
    }
    int CSocketClient::SendData(BYTE* pSendBuf,int nLen)
    {
    int nSendedCount=0;
    if(!m_pServer)
    return 0;

    nSendedCount=Send(pSendBuf,nLen);
    if(SOCKET_ERROR==nSendedCount)
    {
    int nErrorCode=GetLastError();
    if(nErrorCode!=WSAEINPROGRESS&&nErrorCode!=WSAEFAULT&&m_pServer)
    m_pServer->CloseClient(this);
    }
    return nSendedCount;
    }void CSocketClient::OnRecived(BYTE *pRecBuf,int nLen)
    {
    m_nCurUse++;//use flag
    if (nLen<=0 || pRecBuf==NULL) 
    return; for(int i=0;i<nLen;i++)
    {
    m_pRecBuffer[m_nRecPtr]=pRecBuf[i];
    m_nRecPtr=(m_nRecPtr+1)%_max_recive_lentgh;
    }
    }int CSocketClient::ReadData(BYTE *buf, int maxlen)
    {
    EnterCriticalSection(&AccessingEvent); int nLen=min(((m_nRecPtr-m_nDealPtr+_max_recive_lentgh)%_max_recive_lentgh),maxlen);
    for(int i=0;i<nLen;i++)
    {
    buf[i]=m_pRecBuffer[m_nDealPtr];
    m_nDealPtr=(m_nDealPtr+1)%_max_recive_lentgh;
    } LeaveCriticalSection(&AccessingEvent);
    return nLen;
    }int CSocketClient::SendToClient(BYTE *pRecData, int nLen,BYTE pErCode)
    {
    return 0;}/////////////////////////////////////////////////////////////////////////////
    // CSocketListenCSocketListen::CSocketListen(CSocketServer* pServer)
    {
    m_pServer = pServer;
    }CSocketListen::~CSocketListen()
    {
    }
    // Do not edit the following lines, which are needed by ClassWizard.
    #if 0
    BEGIN_MESSAGE_MAP(CSocketListen, CSocket)
    //{{AFX_MSG_MAP(CSocketListen)
    ON_WM_CANCELMODE()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    #endif // 0/////////////////////////////////////////////////////////////////////////////
    // CSocketListen member functionsvoid CSocketListen::OnAccept(int nErrorCode) 
    {
    // TODO: Add your specialized code here and/or call the base class

    CAsyncSocket::OnAccept(nErrorCode); if(m_pServer)
    m_pServer->ProcessPendingAccept();
    }// CSocketServer
    CSocketServer::CSocketServer(char* IODiscribe)
    {
    char cAddr[100];
    memset(cAddr,0,100); UINT nSocketPort=0;
    LPCSTR lpszAddress=NULL;
    m_pListenSocket = NULL; InitializeCriticalSection(&AccessingEvent); m_csName=*IODiscribe; m_bClientServer = TRUE; memcpy(cAddr,IODiscribe,30);
    cAddr[30]=0;

    char *pStr=strstr(cAddr,":");
    if(pStr)
    {
    *pStr=0;
    pStr++;
    lpszAddress=cAddr;}
    else 
    pStr=cAddr; nSocketPort=atoi(pStr); m_pListenSocket = new CSocketListen(this); if (m_pListenSocket->Create(nSocketPort,SOCK_STREAM))//lpszAddress))
    {
    if(!m_pListenSocket->Listen())
    TRACE("SocketServer Listen Error!");
    }
    else 
    TRACE("SocketServer Create Error!");}CSocketServer::~CSocketServer()
    {
    EnterCriticalSection(&AccessingEvent); CloseAllClient(); LeaveCriticalSection(&AccessingEvent);
    DeleteCriticalSection(&AccessingEvent);
    }
    void CSocketServer::MaintainLink()
    {

    }void CSocketServer::ProcessPendingAccept()
    {
    CSocketClient* pSocket = new CSocketClient(this);
    if (m_pListenSocket->Accept(*pSocket))
    {
    EnterCriticalSection(&AccessingEvent);//CHARLIESHAO ADD 20050306
    m_connectionList.AddTail(pSocket);
    LeaveCriticalSection(&AccessingEvent);//CHARLIESHAO ADD 20050306
    }
    else
    {
    EnterCriticalSection(&AccessingEvent);//piano 050731 -b
    delete pSocket;
    pSocket=NULL;
    LeaveCriticalSection(&AccessingEvent);//piano 050731 -e
    }
    }void CSocketServer::CloseAllClient()
    {
    if(m_pListenSocket)
    {
    delete m_pListenSocket;
    m_pListenSocket = NULL;
    }
    while(!m_connectionList.IsEmpty())
    {
    CSocketClient* pSocket = (CSocketClient*)m_connectionList.RemoveHead();
    pSocket->ShutDown();
    pSocket->Close();
    delete pSocket;
    pSocket=NULL;
    }
    }void CSocketServer::CloseClient(CSocketClient * pSocket)
    {
    if(!pSocket)
    return; pSocket->m_bNeedDelete = TRUE;
    }
      

  3.   

    在支持Windows socket的 CTestDlg的OnOK()及 OnInitDialog()都测试过。void CTest55Dlg::OnOK() 
    {
    // TODO: Add extra validation here


    CSocketServer* server=new CSocketServer("192.168.1.100:9000"); while(TRUE)
    {
    server->MaintainLink();
    }

    CDialog::OnOK();
    }
    端口正常打开,不响应Accept~~
      

  4.   

    你确认已经可以通信了了??就是说双方连接正常?如果你是线程里create的socket, 它是不会响应消息的, 因为线程没有消息泵
      

  5.   

    暂时只能确定建立了连接 netstat 确实看到了,而且调试助手也显示连接成功没有线程只是封装了一下socket,对接收到的数据进行保存,并且管理连接的客户端~~
      

  6.   

    程序是托盘~~ 所以我想写个类单独的,跟Dialog分开的。网上的代码有一些是直接在Accept函数里,转到Dialog里响应,显示接收如果没有Dialog是不是就不行了呢?
      

  7.   

    楼主的代码贴得太多了,有点晕....首先问你第一个问题吧,客户端那边connect函数执行成功了吗?确定没有错误?你要是使用CAsyncSocket的话,是基于窗口消息的异步socket方式,确实是需要一个能响应窗口消息的东西才行,你要是不熟悉socket的话,也可以尝试先使用最简单的方式来完成连接试试,便于你对socket程序的理解
      

  8.   

    不一定要dlg, 只要有个窗口实现消息泵就可以了。 你可以在工程 属性, 看看是win console , 还是什么简单的你可以看入口函数 是什么。 
      

  9.   

    是不是主线程有东西在跑啊
    没有线程空间来onaccept?
      

  10.   

    估计是楼主客户端没有调用Connect成功吧。要是成功的话,服务器应该会执行OnAccept的
      

  11.   

    CAsynSocket背后有个隐藏的CSocketWnd对象,自带消息泵
      

  12.   


    谢谢,我看了是文档类型的,貌似MDI多文档~~
      

  13.   

    楼主的问题还没有解决吗?如果可以的话,直接把代码发给我,我帮你看一下吧[email protected]