void CSSLClientAsync::OnConnect(BOOL bConnected) { //无论是否连接成功,都认为已经判断结束 SetCheckConnect(FALSE); //连接完毕,则删除写/错误事件的注册,改成读事件 m_pio->Remove_WriteEvent(this); if (TRUE == bConnected) { SOCKET_IO_INFO("socket connect successed, remote ip: %s, port: %d.", GetRemoteIP(), GetRemotePort()); DoConnect(GetSocketID()); SSL_set_mode(GetSSL(), SSL_MODE_AUTO_RETRY); if (SSL_set_fd(GetSSL(), GetSocket()) != 1) { SOCKET_IO_ERROR("ssl set fd failed"); DoException(GetSocketID(), SOCKET_IO_SSL_CONNECT_FAILED); return; } SSLConnect(); } else { SOCKET_IO_ERROR("socket connect failed, remote ip: %s, port: %d.", GetRemoteIP(), GetRemotePort()); DoException(GetSocketID(), SOCKET_IO_TCP_CONNECT_FAILED); } }
void CSSLClientAsync::OnRecv() { if (GetSSLConnectStatus() == TRUE) { char szBuf[TCP_RECV_SIZE] = {0}; int32_t nRet = SSL_read(GetSSL(), szBuf, TCP_RECV_SIZE); if (nRet > 0) { int32_t nBufSize = nRet; char szIP[32] = {0}; int32_t nPort = 0; S_GetPeerName(GetSocket(), szIP, &nPort); DoRecv(GetSocketID(), szBuf, nBufSize, szIP, nPort); } else if (nRet == 0) { int32_t nErrorCode = SSL_get_error(GetSSL(), nRet); if (SSL_ERROR_ZERO_RETURN == nErrorCode) { //对方关闭socket SOCKET_IO_WARN("recv ssl data error, peer closed."); DoException(GetSocketID(), SOCKET_IO_SSL_RECV_FAILED); } else { SOCKET_IO_ERROR("recv ssl data error."); DoException(GetSocketID(), SOCKET_IO_SSL_RECV_FAILED); } } else { int32_t nErrorCode = SSL_get_error(GetSSL(), nRet); if (SSL_ERROR_WANT_READ == nErrorCode || SSL_ERROR_WANT_WRITE == nErrorCode) { //用select/epoll/iocp的方式应该很少会有这个情况出现 SOCKET_IO_DEBUG("recv ssl data error, buffer is blocking."); } else { SOCKET_IO_ERROR("recv ssl data error, errno: %d.", nErrorCode); DoException(GetSocketID(), SOCKET_IO_SSL_RECV_FAILED); } } } else { SSLConnect(); } }
/** * @ingroup TcpStack * @brief TCP 연결 Thread * @param lpParameter CTcpClientArg 객체 * @returns 0 을 리턴한다. */ THREAD_API TcpClientThread( LPVOID lpParameter ) { CTcpClientArg * pclsArg = (CTcpClientArg *)lpParameter; CLog::Print( LOG_INFO, "TcpClientThread started (%s:%d)", pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); Socket hConn = TcpConnect( pclsArg->m_strIp.c_str(), pclsArg->m_iPort, pclsArg->m_pclsStack->m_clsSetup.m_iTcpConnectTimeout ); if( hConn == INVALID_SOCKET ) { CLog::Print( LOG_ERROR, "%s TcpConnect(%s:%d) error(%d)", __FUNCTION__, pclsArg->m_strIp.c_str(), pclsArg->m_iPort, GetError() ); pclsArg->m_pclsStack->m_clsClientMap.Delete( pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); } else { CTcpComm clsTcpComm; bool bAccept = true; #ifdef USE_TLS if( pclsArg->m_pclsStack->m_clsSetup.m_bUseTls ) { if( SSLConnect( hConn, &clsTcpComm.m_psttSsl ) == false ) { CLog::Print( LOG_ERROR, "%s SSLConnect(%s:%d) error", __FUNCTION__, pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); closesocket( hConn ); pclsArg->m_pclsStack->m_clsClientMap.Delete( pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); bAccept = false; } } #endif if( bAccept ) { if( pclsArg->m_pclsStack->m_clsSetup.m_bUseThreadPipe ) { clsTcpComm.m_hSocket = hConn; snprintf( clsTcpComm.m_szIp, sizeof(clsTcpComm.m_szIp), "%s", pclsArg->m_strIp.c_str() ); clsTcpComm.m_iPort = pclsArg->m_iPort; clsTcpComm.m_bClient = true; if( pclsArg->m_pclsStack->m_clsThreadList.SendCommand( (char *)&clsTcpComm, sizeof(clsTcpComm) ) == false ) { CLog::Print( LOG_ERROR, "%s m_clsThreadList.SendCommand error", __FUNCTION__ ); pclsArg->m_pclsStack->m_clsClientMap.Delete( pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); closesocket( hConn ); } } else { CTcpNoPipeThreadArg * pclsNewArg = new CTcpNoPipeThreadArg(); if( pclsNewArg == NULL ) { CLog::Print( LOG_ERROR, "%s new error", __FUNCTION__ ); closesocket( hConn ); } else { pclsNewArg->m_hSocket = hConn; pclsNewArg->m_strIp = pclsArg->m_strIp; pclsNewArg->m_iPort = pclsArg->m_iPort; pclsNewArg->m_pclsStack = pclsArg->m_pclsStack; pclsNewArg->m_bClient = true; if( StartThread( "TcpNoPipeThread", TcpNoPipeThread, pclsNewArg ) == false ) { CLog::Print( LOG_ERROR, "%s StartThread error", __FUNCTION__ ); closesocket( hConn ); } } pclsArg->m_pclsStack->m_clsClientMap.Delete( pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); } } } CLog::Print( LOG_INFO, "TcpClientThread terminated (%s:%d)", pclsArg->m_strIp.c_str(), pclsArg->m_iPort ); delete pclsArg; #ifdef USE_TLS if( pclsArg->m_pclsStack->m_clsSetup.m_bUseTls ) { ERR_remove_thread_state( NULL ); } #endif return 0; }