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

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 u盘问题:盘符不显示 无媒体
  • ¥50 R语言读取nc按月均值转为tif
  • ¥30 智能车串级pid调参
  • ¥15 visual studio code翻译老是错误
  • ¥20 卫星测高数据的高程转换
  • ¥15 爬取招聘网站数据信息
  • ¥15 安装完tensorflow,import tensorflow as tf后报错,如何解决?
  • ¥15 ultralytics库导出onnx模型,模型失去预测能力
  • ¥15 linux下点对点协议连接2个USB串口的硬件流量控制问题
  • ¥15 SQL数据自动生成问题