/** * @ingroup SnmpStack * @brief SNMP trap 과 같은 단방향 SNMP 메시지를 전송한다. * @param pclsRequest SNMP 메시지 * @returns 성공하면 true 를 리턴하고 실패하면 false 를 리턴한다. */ bool CSnmpSession::SendRequest( CSnmpMessage * pclsRequest ) { char szSend[SNMP_MAX_PACKET_SIZE]; int iSendLen; if( m_hSocket == INVALID_SOCKET ) { if( Open() == false ) return false; } if( m_strUserName.empty() == false ) { static uint8_t szEngineId[] = { 0x80, 0x00, 0x00, 0x04, 0x80, 0x00 }; pclsRequest->m_cVersion = SNMP_VERSION_3; pclsRequest->m_iMsgId = ++m_iRequestId; pclsRequest->m_iRequestId = pclsRequest->m_iMsgId; pclsRequest->m_strMsgAuthEngineId = m_strAuthEngineId; pclsRequest->m_strMsgUserName = m_strUserName; pclsRequest->m_strUserId = m_strUserName; pclsRequest->m_strAuthPassWord = m_strAuthPassWord; pclsRequest->m_strPrivPassWord = m_strPrivPassWord; pclsRequest->m_strContextEngineId.append( (char *)szEngineId, sizeof(szEngineId) ); pclsRequest->SetPrivParams( ); pclsRequest->SetAuthParams( ); } else { pclsRequest->m_strCommunity = m_strCommunity; pclsRequest->m_iRequestId = ++m_iRequestId; } iSendLen = pclsRequest->MakePacket( szSend, sizeof(szSend) ); if( iSendLen == -1 ) { CLog::Print( LOG_ERROR, "%s MakePacket error", __FUNCTION__ ); return false; } if( m_bTcp ) { if( TcpSend( m_hSocket, szSend, iSendLen ) == false ) { CLog::Print( LOG_ERROR, "%s TcpSend error", __FUNCTION__ ); return false; } } else { if( UdpSend( m_hSocket, szSend, iSendLen, m_iIp, m_sPort ) == false ) { CLog::Print( LOG_ERROR, "%s UdpSend error", __FUNCTION__ ); return false; } } return true; }
BOOL MsgMng::Send(ULONG host, int port_no, ULONG command, const char *message, const char *exMsg) { char buf[MAX_UDPBUF]; int trans_len; MakeMsg(buf, command, message, exMsg, &trans_len); return UdpSend(host, port_no, buf, trans_len); }
int main (int argc, char *argv[]) { int Rc; LPUDPSOCK lpSock=NULL; char szVer [128]; int nTries=0; unsigned short nPort; if (argc<2) Usage(); if (argc==3 && strcmp (argv[1], "-v")==0) Tcp4uEnableLog (LOG4U_DUMP); Tcp4uVer (szVer, sizeof szVer); printf ("Using %s\n", szVer); Tcp4uInit(); nPort = Udp4uServiceToPort ("echo"); printf ("echo port is %u\n", nPort); Rc = UdpInit (& lpSock, argv[argc-1], nPort, 0); if (Rc>=TCP4U_SUCCESS) Rc = UdpBind (lpSock, TRUE, UDP4U_CLIENT); if (Rc<TCP4U_SUCCESS) { printf ("Error %d/%d: <%s>\n", Rc, errno, Tcp4uErrorString (Rc)); return 0; } /* send 3 datagrams */ nTries++; do { Rc = UdpSend (lpSock, STRING, sizeof STRING, 0, HLOG); if (Rc>=TCP4U_SUCCESS) Rc= UdpRecv (lpSock, buf, sizeof buf, 5, HLOG); nTries++; } while (nTries <= 3 && Rc==TCP4U_TIMEOUT); if (Rc>=TCP4U_SUCCESS) printf ("Server sends %d bytes. String <%s>\n", Rc, buf); else printf ("Error %d/%d: <%s>\n", Rc, errno, Tcp4uErrorString (Rc)); if (lpSock!=NULL) UdpCleanup (lpSock); Tcp4uCleanup(); return 0; }
/** * @ingroup SipStack * @brief UDP SIP 메시지 수신 쓰레드에 종료 SIP 메시지를 전송하고 SIP stack 쓰레드에 종료 이벤트를 설정한 후, 모든 쓰레드가 종료할 때까지 대기한 후, * 소켓 핸들을 종료시킨다. * @returns true 를 리턴한다. */ bool CSipStack::_Stop( ) { m_bStopEvent = true; if( m_clsSetup.m_iLocalUdpPort > 0 ) { // SIP 메시지 수신 쓰레드가 N 개 실행되므로 N 초 대기하는 것을 방지하기 위한 코드이다. Socket hSocket = UdpSocket(); if( hSocket != INVALID_SOCKET ) { for( int i = 0; i < m_clsSetup.m_iUdpThreadCount; ++i ) { UdpSend( hSocket, "\r\n", 2, "127.0.0.1", m_clsSetup.m_iLocalUdpPort ); } closesocket( hSocket ); } } gclsSipQueue.BroadCast(); // 모든 쓰레드가 종료할 때까지 대기한다. while( m_iUdpThreadRunCount > 0 || m_iTcpThreadRunCount > 0 || m_bStackThreadRun || GetTcpConnectingCount() > 0 ) { MiliSleep( 20 ); } if( m_hUdpSocket != INVALID_SOCKET ) { closesocket( m_hUdpSocket ); m_hUdpSocket = INVALID_SOCKET; } if( m_hTcpSocket != INVALID_SOCKET ) { closesocket( m_hTcpSocket ); m_hTcpSocket = INVALID_SOCKET; } m_clsTcpThreadList.Final(); m_clsTcpSocketMap.DeleteAll(); #ifdef USE_TLS if( m_hTlsSocket != INVALID_SOCKET ) { closesocket( m_hTlsSocket ); m_hTlsSocket = INVALID_SOCKET; } m_clsTlsThreadList.Final(); m_clsTlsSocketMap.DeleteAll(); SSLServerStop(); #endif DeleteAllTransaction(); m_bStopEvent = false; return true; }
/** * @ingroup SnmpStack * @brief SNMP 요청 메시지를 전송한 후, 이에 대한 응답 메시지를 수신한다. * @param pclsRequest SNMP 요청 메시지 * @param pclsResponse SNMP 응답 메시지 * @returns 성공하면 true 를 리턴하고 실패하면 false 를 리턴한다. */ bool CSnmpSession::SendRecv( CSnmpMessage * pclsRequest, CSnmpMessage * pclsResponse ) { int iSendLen, iRecvLen = 0, n; bool bRes = false; if( m_hSocket == INVALID_SOCKET ) { if( Open() == false ) return false; } if( m_bTcp ) { char szSend[SNMP_MAX_PACKET_SIZE], szRecv[SNMP_MAX_PACKET_SIZE]; int iWantRecvLen = 0; iSendLen = pclsRequest->MakePacket( szSend, sizeof(szSend) ); if( iSendLen == -1 ) { CLog::Print( LOG_ERROR, "%s MakePacket error", __FUNCTION__ ); return false; } if( TcpSend( m_hSocket, szSend, iSendLen ) == false ) { CLog::Print( LOG_ERROR, "%s TcpSend error", __FUNCTION__ ); return false; } while( 1 ) { n = TcpRecv( m_hSocket, szRecv + iRecvLen, sizeof(szRecv) - iRecvLen, m_iMiliTimeout / 1000 ); if( n <= 0 ) { CLog::Print( LOG_ERROR, "%s recv error(%d)", __FUNCTION__, GetError() ); return false; } iRecvLen += n; if( iWantRecvLen <= 0 ) { iWantRecvLen = pclsResponse->GetPacketLen( szRecv, iRecvLen ); } if( iWantRecvLen > 0 ) { if( iRecvLen == iWantRecvLen ) break; } } if( pclsResponse->ParsePacket( szRecv, iRecvLen ) > 0 ) { if( m_bDebug ) { LogPacket( szRecv, iRecvLen ); } if( pclsRequest->m_iRequestId == pclsResponse->m_iRequestId || ( pclsRequest->m_iMsgId > 0 && pclsRequest->m_iMsgId == pclsResponse->m_iMsgId ) ) { bRes = true; } } } else { char szSend[SNMP_MAX_PACKET_SIZE], szRecv[SNMP_MAX_PACKET_SIZE]; struct pollfd arrPoll[1]; uint32_t iIp; uint16_t sPort; iSendLen = pclsRequest->MakePacket( szSend, sizeof(szSend) ); if( iSendLen == -1 ) { CLog::Print( LOG_ERROR, "%s MakePacket error", __FUNCTION__ ); return false; } for( int iSend = 0; iSend <= m_iReSendCount; ++iSend ) { if( UdpSend( m_hSocket, szSend, iSendLen, m_iIp, m_sPort ) == false ) { CLog::Print( LOG_ERROR, "%s UdpSend error", __FUNCTION__ ); return false; } TcpSetPollIn( arrPoll[0], m_hSocket ); POLL_START: n = poll( arrPoll, 1, m_iMiliTimeout ); if( n > 0 ) { iRecvLen = sizeof(szRecv); if( UdpRecv( m_hSocket, szRecv, &iRecvLen, &iIp, &sPort ) ) { if( pclsResponse->ParsePacket( szRecv, iRecvLen ) > 0 ) { if( m_bDebug ) { LogPacket( szRecv, iRecvLen ); } if( pclsRequest->m_iRequestId == pclsResponse->m_iRequestId || ( pclsRequest->m_iMsgId > 0 && pclsRequest->m_iMsgId == pclsResponse->m_iMsgId ) ) { bRes = true; break; } } // 원하는 응답이 수신되지 않으면 다시 수신 대기로 진입한다. goto POLL_START; } } } } return bRes; }
BOOL MsgMng::UdpSend(ULONG host_addr, int port_no, const char *buf) { return UdpSend(host_addr, port_no, buf, (int)strlen(buf) +1); }