barry_di 2019-08-19 14:29 采纳率: 100%
浏览 847
已结题

C++ TCP CAsyncSocket一服务端对应多客户端的问题

CNetTcpLsn是CAsyncSocket的一个派生类,服务端接收客户端连接,同时要把数据发给连接的客户端,客户的socket保存在m_ClientSockList里,当发送函数里调用Num = pSock->Send(_buf,nLen,0) 失败时,想立即把客户端的socket Close并删掉,但是一close就会崩溃,原因是close内部的KillSocket里断言失败,如何才能实现Send失败时,立马释放代表客户端的socket

void CNetTcpLsn::OnAccept(int nErrorCode)
{
if (nErrorCode == 0)
{
CNetAcpSock* pSock = new CNetAcpSock(m_pBase) ;
if (Accept(*pSock))
{

pSock->AsyncSelect(FD_READ|FD_CONNECT|FD_CLOSE|FD_OOB) ;
pSock->m_bConnect = TRUE;
m_ClientSockList.push_back(pSock);
m_bConnect = TRUE ; //连接标志
SOCKADDR clientAddr;
int iLength = sizeof(sockaddr);
if(pSock->GetPeerName((struct sockaddr * )&clientAddr, &iLength))
{
sockaddr_in * pSin = (sockaddr_in *)&clientAddr;
m_pBase->m_ConAddr.Format("%s:%d",inet_ntoa(pSin->sin_addr),ntohs(pSin->sin_port));
}else
m_pBase->m_ConAddr = "0.0.0.0:0";
}
else
{
delete pSock ;
pSock = NULL ;
}
}

CAsyncSocket::OnAccept(nErrorCode);

}


//发送函数
int CNetTcpLsn::_Send(char _buf, int nLen)
{
int Num = 0 ;
vector<CNetAcpSock
>::iterator iter;
for (iter=m_ClientSockList.begin();iter!=m_ClientSockList.end();++iter)
{
CNetAcpSock* pSock = (CNetAcpSock*) *iter;

    if (pSock)
    {
        Num = pSock->Send(_buf,nLen,0) ;
        if (Num == SOCKET_ERROR)
        {
            int ret = GetLastError() ;
            if( ret != 10035)
            {
                if (pSock->m_bConnect)
                {
                    pSock->m_bConnect = FALSE ;//连接中断
                }
            }
        }
        else
        {
            if (!m_bConnect)
            {
                pSock->m_bConnect = TRUE;
            }   
        }
    }
}

return Num ;

}


void PASCAL CAsyncSocket::KillSocket(SOCKET hSocket, CAsyncSocket* pSocket)
{
// assert会失败CAsyncSocket::LookupHandle(hSocket, FALSE)返回是NULL
ASSERT(CAsyncSocket::LookupHandle(hSocket, FALSE) != NULL);

_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;

CAsyncSocket::DetachHandle(hSocket, FALSE);
if (pState->m_hSocketWindow != NULL)
{
    ::PostMessage(pState->m_hSocketWindow, WM_SOCKET_DEAD,
        (WPARAM)hSocket, 0L);
    CAsyncSocket::AttachHandle(hSocket, pSocket, TRUE);
}

}

  • 写回答

1条回答 默认 最新

  • 关注
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 网上下载的3DMAX模型,不显示贴图怎么办
  • ¥15 关于#stm32#的问题:寻找一块开发版,作为智能化割草机的控制模块和树莓派主板相连,要求:最低可控制 3 个电机(两个驱动电机,1 个割草电机),其次可以与树莓派主板相连电机照片如下:
  • ¥15 Mac(标签-IDE|关键词-File) idea
  • ¥15 潜在扩散模型的Unet特征提取
  • ¥15 iscsi服务无法访问,如何解决?
  • ¥15 感应式传感器制作的感应式讯响器
  • ¥15 如何使用SC92F8003固件库解析私有协议数据?
  • ¥15 如何在音频中嵌入字符串(水印)信息进行传递
  • ¥30 plc怎么以设计说明书申请软著
  • ¥15 硬盘识别不了,需要初始化,可我的数据怎么办