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条回答 默认 最新

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

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮