📄 o22siost.cpp
字号:
{ // Timeout! m_pStreamEventCallbackFunc(pTempStreamItem->nIpAddress, m_pStreamEventParam, SIOMM_TIME_OUT); // Set this flag so we don't check for another timeout with this stream item. // This will be reset by the next packet we receive for this item. pTempStreamItem->bTimeoutSent = TRUE; } } // Get the next item in the list pTempStreamItem = pTempStreamItem->pNext; }#ifdef _WIN32 LeaveCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_unlock(&m_StreamCriticalSection);//#endif return SIOMM_OK;}LONG O22SnapIoStream::SetCallbackFunctions(STREAM_CALLBACK_PROC pStartThreadCallbackFunc, void * pStartThreadParam, STREAM_EVENT_CALLBACK_PROC pStreamEventCallbackFunc, void * pStreamEventParam, STREAM_CALLBACK_PROC pStopThreadCallbackFunc, void * pStopThreadParam)//-------------------------------------------------------------------------------------------------// The pStartThreadCallbackFunc and pStopThreadCallbackFunc callback functions are used// to help users of this class. They were mainly added to help the ActiveX wrapper. // Their use is optional. Set them to NULL if not needed. They are only called when the// listener thread has started or stopped, which is done in the OpenStreaming() and // CloseStreaming() functions. //// The pStreamEventCallbackFunc callback is used to inform the user of this class that// a stream packet has arrived or that a timeout has occured.//// The pStartThreadParam, pStreamEventParam, and pStopThreadParam parameters are passed// along with each corresponding callback function. They are useful for passing information// to the callback, such as a pointer.//-------------------------------------------------------------------------------------------------{ // Set all the callback functions and parameters m_pStartThreadCallbackFunc = pStartThreadCallbackFunc; m_pStreamEventCallbackFunc = pStreamEventCallbackFunc; m_pStopThreadCallbackFunc = pStopThreadCallbackFunc; m_pStartThreadParam = pStartThreadParam; m_pStreamEventParam = pStreamEventParam; m_pStopThreadParam = pStopThreadParam; return SIOMM_OK;};LONG O22SnapIoStream::StartStreamListening(char * pchIpAddressArg, long nTimeoutMS)//-------------------------------------------------------------------------------------------------// Start listening to a particular I/O unit. No connection is actually made. We just listen for // packets. We can listen to more than one at a time.//// The timeout value is used to generate an error event if a packet hasn't been received// in the timeout period. //-------------------------------------------------------------------------------------------------{ // Create and add the new item O22StreamItem * pNewStreamItem = new O22StreamItem; if (pNewStreamItem) { // make sure the new object is all zeroes memset(pNewStreamItem, 0, sizeof(O22StreamItem)); // Set the IP address and timeout pNewStreamItem->nTimeout = nTimeoutMS; pNewStreamItem->nIpAddress = inet_addr(pchIpAddressArg); // Get the current tick count#ifdef _WIN32 pNewStreamItem->nLastPacketTickCount = GetTickCount(); // GetTickCount returns the number of milliseconds that have // elapsed since the system was started.#endif#ifdef _LINUX tms DummyTime; pNewStreamItem->nLastPacketTickCount = times(&DummyTime); // times() returns the number of milliseconds that have // elapsed since the system was started.#endif // A temp stream item for traversing the list O22StreamItem * pTempStreamItem;#ifdef _WIN32 EnterCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_lock(&m_StreamCriticalSection);//#endif // Check if the list is empty if (pStreamList) { // The list is not empty, so add the new item only if doesn't already exist. pTempStreamItem = pStreamList; while (pTempStreamItem->pNext != NULL) { // Look for a match, in which case we won't need to add it. if (pTempStreamItem->nIpAddress == pNewStreamItem->nIpAddress) { delete pNewStreamItem; break; } // Get the next item pTempStreamItem = pTempStreamItem->pNext; } // If we made it this far, we're at the end of the list. // Add the new item here. pTempStreamItem->pNext = pNewStreamItem; // Increment our count of stream items nStreamListCount++; } else { // The list is empty, so add the new item here pStreamList = pNewStreamItem; // Increment our count of stream items nStreamListCount++; }#ifdef _WIN32 LeaveCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_unlock(&m_StreamCriticalSection);//#endif } else { return SIOMM_ERROR_OUT_OF_MEMORY; } // Set the listen flag. This may have been set already, but it guarantees // that we'll be listening now. m_bListenToStreaming = TRUE; // Everything must be okay. return SIOMM_OK;}LONG O22SnapIoStream::StopStreamListening(char * pchIpAddressArg)//-------------------------------------------------------------------------------------------------// Stop listening for packets from a certain IP address//-------------------------------------------------------------------------------------------------{ // ?? The method of using a flag to stop the thread might cause one more stream packet // to be received and processed! // Get the IP address in integer form unsigned long nIpAddressArg = inet_addr(pchIpAddressArg);#ifdef _WIN32 EnterCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_lock(&m_StreamCriticalSection);//#endif // Check that the stream list has something in it. if (pStreamList) { // A few stream items for traversing the stream list O22StreamItem * pTempStreamItem; O22StreamItem * pTempNextStreamItem; // Get the head of the list pTempStreamItem = pStreamList; // Check the IP address of the head item if (pStreamList->nIpAddress == nIpAddressArg) { // Remove the head item pTempStreamItem = pStreamList; pStreamList = pStreamList->pNext; // Delete the head item and decrement the count delete pTempStreamItem; nStreamListCount--; } else { // The head item didn't match, so start looping through the list pTempStreamItem = pStreamList; pTempNextStreamItem = pTempStreamItem->pNext; while (pTempNextStreamItem != NULL) { // Check the IP address if (pTempNextStreamItem->nIpAddress == nIpAddressArg) { // Found a match! // Remove this item from the list pTempStreamItem->pNext = pTempNextStreamItem->pNext; // Delete this item and decrement the list count delete pTempNextStreamItem; nStreamListCount--; // Break out of the loop break; } else { // Get the next item in the list pTempStreamItem = pTempNextStreamItem; pTempNextStreamItem = pTempNextStreamItem->pNext; } } } }#ifdef _WIN32 LeaveCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_unlock(&m_StreamCriticalSection);//#endif return SIOMM_OK;}LONG O22SnapIoStream::StreamHandler()//-------------------------------------------------------------------------------------------------// This is the main worker function. It is called repeatedly by the listening thread, StreamThread().// It checks the socket for new packets and determines if the user is interested in them.//-------------------------------------------------------------------------------------------------{ LONG nResult; fd_set fds; sockaddr_in SourceAddress; BOOL bCriticalSectionFlag = TRUE; // used to tell if we need to leave the critical // at the end of the function section#ifdef _WIN32 int nSourceLen = sizeof(SourceAddress);#endif//#ifdef _LINUX socklen_t nSourceLen = sizeof(SourceAddress);//#endif//gy changed 5.28 // Timeout structure for sockets, so to zeros. timeval tvStreamTimeOut; tvStreamTimeOut.tv_sec = 0; tvStreamTimeOut.tv_usec = 0; // Check that we have a valid socket if (INVALID_SOCKET == m_StreamSocket) { return SIOMM_ERROR_NOT_CONNECTED; } FD_ZERO(&fds); FD_SET(m_StreamSocket, &fds); // Is the recv ready? // Note that Param#1 of select() is ignored by Windows. What should it be in other systems? if (0 == select(m_StreamSocket + 1, &fds, NULL, NULL, &tvStreamTimeOut)) { // we timed-out, which doesn't really matter. The timeout was set to zero. // Basically, it means no packets are ready. // Return a timeout error. The caller will know what to do. This will be a normal condition. return SIOMM_TIME_OUT; } // The response is ready, so recv it. nResult = recvfrom(m_StreamSocket, (char*)m_pbyLastStreamBlock, m_nStreamLength, 0 /*??*/, (sockaddr*)&SourceAddress, &nSourceLen); // Check for socket error if (SOCKET_ERROR == nResult) {#ifdef _WIN32 nResult = WSAGetLastError(); // for checking the specific error#endif return SIOMM_ERROR; } // Check the length if (m_nStreamLength != nResult) { return SIOMM_ERROR_RESPONSE_BAD; }#ifdef _WIN32 EnterCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_lock(&m_StreamCriticalSection);//#endif // Check if this packet is from a source that we care about O22StreamItem * pTempStreamItem; pTempStreamItem = pStreamList; while (pTempStreamItem != NULL) { if (pTempStreamItem->nIpAddress == SourceAddress.sin_addr.s_addr ) { // We have a match, so process that packet and inform the client. if (SIOMM_STREAM_TYPE_STANDARD == m_nStreamType) { // Copy the header memcpy(&(m_LastStreamBlock.nHeader), m_pbyLastStreamBlock, 4); // Copy the data block memcpy(&(m_LastStreamBlock.byData), m_pbyLastStreamBlock + 4, sizeof(SIOMM_StreamStandardBlock) - 8); } else if (SIOMM_STREAM_TYPE_CUSTOM == m_nStreamType) { // Copy the data block memcpy(&m_LastStreamBlock, m_pbyLastStreamBlock, m_nStreamLength); } // Set the source IP address// m_LastStreamBlock.nTCPIPAddress = O22_SWAP_BYTES_LONG(SourceAddress.sin_addr.s_addr); m_LastStreamBlock.nTCPIPAddress = O22MAKELONG(O22BYTE3(SourceAddress.sin_addr.s_addr), O22BYTE2(SourceAddress.sin_addr.s_addr), O22BYTE1(SourceAddress.sin_addr.s_addr), O22BYTE0(SourceAddress.sin_addr.s_addr)); // Get the tickcount#ifdef _WIN32 // GetTickCount returns the number of milliseconds that have // elapsed since the system was started. pTempStreamItem->nLastPacketTickCount = GetTickCount(); #endif#ifdef _LINUX tms DummyTime; // times() returns the number of milliseconds that have elapsed since the system was started pTempStreamItem->nLastPacketTickCount = times(&DummyTime); #endif // Reset the timeout sent flag. pTempStreamItem->bTimeoutSent = FALSE;#ifdef _WIN32 LeaveCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_unlock(&m_StreamCriticalSection);//#endif // Call the callback function m_pStreamEventCallbackFunc(m_LastStreamBlock.nTCPIPAddress, m_pStreamEventParam, SIOMM_OK); bCriticalSectionFlag = FALSE; break; } // No match yet, so keep traversing the list pTempStreamItem = pTempStreamItem->pNext; } // Make sure we're out of the critical section if (bCriticalSectionFlag) {#ifdef _WIN32 LeaveCriticalSection(&m_StreamCriticalSection);#endif//#ifdef _LINUX pthread_mutex_unlock(&m_StreamCriticalSection);//#endif } // Everything must be good if we got here return SIOMM_OK;}LONG O22SnapIoStream::GetLastStreamStandardBlockEx(SIOMM_StreamStandardBlock * pStreamData)//-------------------------------------------------------------------------------------------------// Gets the last stream block that was received. If this function isn't called after receiving// a packet notification event (STREAM_EVENT_CALLBACK_PROC callback), the data will lost when// the next packet is received.//-------------------------------------------------------------------------------------------------{ int nTemp; // Flip-flop all the bytes so they're in the right order for the PC for (int i = 4 ; i < sizeof(SIOMM_StreamStandardBlock) ; i+=4) { nTemp = O22MAKELONG(m_LastStreamBlock.byData[i-4], m_LastStreamBlock.byData[i-3], m_LastStreamBlock.byData[i-2], m_LastStreamBlock.byData[i-1]); memcpy((void*)(((char*)pStreamData) + i), &nTemp, 4); } // Set the header pStreamData->nHeader = m_LastStreamBlock.nHeader; // Set the source IP address pStreamData->nTCPIPAddress = m_LastStreamBlock.nTCPIPAddress; return SIOMM_OK;}LONG O22SnapIoStream::GetLastStreamCustomBlockEx(SIOMM_StreamCustomBlock * pStreamData)//-------------------------------------------------------------------------------------------------// Gets the last stream block that was received. If this function isn't called after receiving// a packet notification event (STREAM_EVENT_CALLBACK_PROC callback), the data will lost when// the next packet is received.//-------------------------------------------------------------------------------------------------{ // Copy the data. memcpy(pStreamData, &m_LastStreamBlock, sizeof(m_LastStreamBlock)); return SIOMM_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -