XnStatus ServerSocketInConnection::ConnectSocket(XN_SOCKET_HANDLE& hSocket, const XnChar* strIP, XnUInt16 nPort) { XnStatus nRetVal = XN_STATUS_OK; (void)strIP; //Ignore IP parameter - accept connections from any IP. XN_SOCKET_HANDLE hListenSocket = NULL; nRetVal = xnOSCreateSocket(XN_OS_TCP_SOCKET, "0.0.0.0", nPort, &hListenSocket); XN_IS_STATUS_OK_LOG_ERROR("Create data listen socket", nRetVal); nRetVal = xnOSBindSocket(hListenSocket); if (nRetVal != XN_STATUS_OK) { xnOSCloseSocket(hListenSocket); XN_IS_STATUS_OK_LOG_ERROR("Bind data listen socket", nRetVal); } nRetVal = xnOSListenSocket(hListenSocket); if (nRetVal != XN_STATUS_OK) { xnOSCloseSocket(hListenSocket); XN_IS_STATUS_OK_LOG_ERROR("Listen to data socket", nRetVal); } xnLogVerbose(XN_MASK_SOCKETS, "Server accepting %s:%u...", strIP, nPort); nRetVal = xnOSAcceptSocket(hListenSocket, &hSocket, XN_WAIT_INFINITE); xnOSCloseSocket(hListenSocket); XN_IS_STATUS_OK_LOG_ERROR("Accept data socket", nRetVal); xnLogVerbose(XN_MASK_SOCKETS, "Server accepted connection on port %u", nPort); return XN_STATUS_OK; }
void XnServerSession::Free() { if (m_hThread != NULL) { xnOSWaitAndTerminateThread(&m_hThread, 2000); m_hThread = NULL; } if (m_hStreamsLock != NULL) { xnOSCloseCriticalSection(&m_hStreamsLock); m_hStreamsLock = NULL; } if (m_hCommLock != NULL) { xnOSCloseCriticalSection(&m_hCommLock); m_hCommLock = NULL; } if (m_pStreamDataSet != NULL) { XnStreamDataSetDestroy(&m_pStreamDataSet); m_pStreamDataSet = NULL; } if (m_hSocket != NULL) { xnOSCloseSocket(m_hSocket); m_hSocket = NULL; } m_privateIncomingPacker.Free(); m_privateOutgoingPacker.Free(); }
XnStatus SyncSocketConnection::Connect() { if (IsConnected()) { return XN_STATUS_OK; } XnStatus nRetVal = xnOSCreateSocket(XN_OS_TCP_SOCKET, m_strIP, m_nPort, &m_hSocket); if (nRetVal != XN_STATUS_OK) { xnLogError(XN_MASK_SYNC_SOCKET, "Failed to create socket %s:%u: %s", m_strIP, m_nPort, xnGetStatusString(nRetVal)); m_hSocket = NULL; return nRetVal; } nRetVal = xnOSConnectSocket(m_hSocket, CONNECT_TIMEOUT); if (nRetVal != XN_STATUS_OK) { xnLogError(XN_MASK_SYNC_SOCKET, "Failed to connect socket %s:%u: %s", m_strIP, m_nPort, xnGetStatusString(nRetVal)); xnOSCloseSocket(m_hSocket); m_hSocket = NULL; return nRetVal; } return XN_STATUS_OK; }
void XnSensorServer::CheckForNewClients(XnUInt32 nTimeout) { XnStatus nRetVal = XN_STATUS_OK; // run in loop until we break due to timeout XN_SOCKET_HANDLE hClientSocket; for (;;) { nRetVal = xnOSAcceptSocket(m_hListenSocket, &hClientSocket, nTimeout); if (nRetVal == XN_STATUS_OS_NETWORK_TIMEOUT) { return; } else if (nRetVal != XN_STATUS_OK) { //Any other error beside timeout is not expected, but we treat it the same. xnLogWarning(XN_MASK_SENSOR_SERVER, "failed to accept connection: %s", xnGetStatusString(nRetVal)); } else { xnLogInfo(XN_MASK_SENSOR_SERVER, "New client trying to connect..."); //TODO: Check if we don't have too many clients nRetVal = AddSession(hClientSocket); if (nRetVal != XN_STATUS_OK) { xnLogWarning(XN_MASK_SENSOR_SERVER, "Failed to add new client: %s", xnGetStatusString(nRetVal)); xnOSCloseSocket(hClientSocket); //Still in loop } } } }
void SyncSocketConnection::Disconnect() { if (m_hSocket != NULL) { xnOSCloseSocket(m_hSocket); m_hSocket = NULL; } }
void XnSensorClient::DestroyIOStreamImpl(XnIOStream* pStream) { XN_DELETE(pStream); if (m_hSocket != NULL) { xnOSCloseSocket(m_hSocket); m_hSocket = NULL; } }
XN_C_API XnStatus xnOSAcceptSocket(XN_SOCKET_HANDLE ListenSocket, XN_SOCKET_HANDLE* AcceptSocketPtr, XnUInt32 nMillisecondsTimeout) { // Local function variables XnInt32 nRetVal = 0; struct timeval selectTimeOut; struct timeval* pTimeout = xnOSMillisecsToTimeVal(nMillisecondsTimeout, &selectTimeOut); fd_set fdReadHandles; XN_SOCKET_HANDLE AcceptSocket = NULL; // Validate the input/output pointers (to make sure none of them is NULL) XN_VALIDATE_INPUT_PTR(ListenSocket); XN_VALIDATE_OUTPUT_PTR(AcceptSocketPtr); // Make sure the actual socket handle isn't NULL XN_RET_IF_NULL(ListenSocket->Socket, XN_STATUS_OS_INVALID_SOCKET); // Wait for connection request XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_CONDITION_IS_CONST_WARNING_ID); FD_ZERO(&fdReadHandles); FD_SET(ListenSocket->Socket, &fdReadHandles); XN_PRAGMA_STOP_DISABLED_WARNING_SECTION; nRetVal = select(1 /* ignored */, &fdReadHandles, NULL, NULL, pTimeout); if (nRetVal == 0) { return (XN_STATUS_OS_NETWORK_TIMEOUT); } else if (nRetVal == SOCKET_ERROR) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_NETWORK_SOCKET_ACCEPT_FAILED, XN_MASK_OS, "select() returned WinSock error: %d", WSAGetLastError()); } // Allocate a new socket XN_VALIDATE_ALIGNED_CALLOC(*AcceptSocketPtr, xnOSSocket, 1, XN_DEFAULT_MEM_ALIGN); AcceptSocket = *AcceptSocketPtr; // Accept the socket and make sure it succeeded AcceptSocket->nSocketAddressLen = sizeof(AcceptSocket->SocketAddress); AcceptSocket->Socket = accept(ListenSocket->Socket, (sockaddr*)&AcceptSocket->SocketAddress, &AcceptSocket->nSocketAddressLen); if (AcceptSocket->Socket == INVALID_SOCKET) { xnOSCloseSocket(AcceptSocket); xnOSFreeAligned(*AcceptSocketPtr); return(XN_STATUS_OS_NETWORK_SOCKET_ACCEPT_FAILED); } // All is good... return (XN_STATUS_OK); }
XnBool XnSensorServer::ShutdownIfPossible() { XnStatus nRetVal = XN_STATUS_OK; // lock sessions list XnAutoCSLocker locker(m_hSessionsLock); // check if no sessions and no sensors if (CanShutdown()) { // lock the running lock XnAutoMutexLocker serverRunningLock(m_hServerRunningMutex, XN_SENSOR_SERVER_RUNNING_MUTEX_TIMEOUT); nRetVal = serverRunningLock.GetStatus(); if (nRetVal == XN_STATUS_OK) { // make sure no client is waiting to connect CheckForNewClients(0); // re-check shutdown condition if (CanShutdown()) { xnLogInfo(XN_MASK_SENSOR_SERVER, "No sensors are open and no client is connected. Shutting down..."); // reset the event (to notify server is no longer up) nRetVal = xnOSResetEvent(m_hServerRunningEvent); if (nRetVal != XN_STATUS_OK) { xnLogWarning(XN_MASK_SENSOR_SERVER, "Failed to reset sensor server event: %s - proceeding with shutdown.", xnGetStatusString(nRetVal)); XN_ASSERT(FALSE); } // and close the socket (to free the port for another server) xnOSCloseSocket(m_hListenSocket); m_hListenSocket = NULL; return TRUE; } } } return FALSE; }
void XnSensorServer::Free() { if (m_hServerRunningEvent != NULL) { xnOSCloseEvent(&m_hServerRunningEvent); m_hServerRunningEvent = NULL; } if (m_hListenSocket != NULL) { xnOSCloseSocket(m_hListenSocket); m_hListenSocket = NULL; } if (m_hSessionsLock != NULL) { xnOSCloseCriticalSection(&m_hSessionsLock); m_hSessionsLock = NULL; } }
void XnSensorServer::ShutdownServer() { XnStatus nRetVal = XN_STATUS_OK; XnAutoMutexLocker serverRunningLock(m_hServerRunningMutex, XN_SENSOR_SERVER_RUNNING_MUTEX_TIMEOUT); nRetVal = serverRunningLock.GetStatus(); if (nRetVal != XN_STATUS_OK) { //This could mean there's another server/client that's frozen and they're jamming the mutex... xnLogWarning(XN_MASK_SENSOR_SERVER, "Failed to lock server mutex: %s - proceeding with shutdown.", xnGetStatusString(nRetVal)); XN_ASSERT(FALSE); } if (m_hServerRunningEvent != NULL) { nRetVal = xnOSResetEvent(m_hServerRunningEvent); if (nRetVal != XN_STATUS_OK) { xnLogWarning(XN_MASK_SENSOR_SERVER, "Failed to reset sensor server event: %s - proceeding with shutdown.", xnGetStatusString(nRetVal)); XN_ASSERT(FALSE); } xnOSCloseEvent(&m_hServerRunningEvent); m_hServerRunningEvent = NULL; } XN_ASSERT(m_sessions.IsEmpty()); if (m_hListenSocket != NULL) { xnOSCloseSocket(m_hListenSocket); m_hListenSocket = NULL; } if (m_hSessionsLock != NULL) { xnOSCloseCriticalSection(&m_hSessionsLock); m_hSessionsLock = NULL; } }
XnStatus XnSensorClient::CreateIOStreamImpl(const XnChar *strConnectionString, XnIOStream *&pStream) { XnStatus nRetVal = XN_STATUS_OK; nRetVal = xnOSCreateSocket(XN_OS_TCP_SOCKET, XN_SENSOR_SERVER_IP_ADDRESS, XN_SENSOR_SERVER_PORT, &m_hSocket); XN_IS_STATUS_OK(nRetVal); // connect to server XnUInt64 nStart; xnOSGetTimeStamp(&nStart); nRetVal = XN_STATUS_OS_NETWORK_TIMEOUT; for (XnUInt32 nRetries = 0; (nRetries < XN_SENSOR_CLIENT_CONNECT_RETRIES) && (nRetVal != XN_STATUS_OK); nRetries++) { nRetVal = xnOSConnectSocket(m_hSocket, XN_SENSOR_CLIENT_WAIT_FOR_SERVER); } if (nRetVal == XN_STATUS_OS_NETWORK_TIMEOUT) { xnLogError(XN_MASK_SENSOR_CLIENT, "Got timeout waiting for server"); return nRetVal; } else if (nRetVal != XN_STATUS_OK) { xnLogError(XN_MASK_SENSOR_CLIENT, "Got an error trying to connect to server socket: %s", xnGetStatusString(nRetVal)); return nRetVal; } XnIONetworkStream *pNetworkStream = XN_NEW(XnIONetworkStream, m_hSocket); if (pNetworkStream == NULL) { xnOSCloseSocket(m_hSocket); return XN_STATUS_ALLOC_FAILED; } pNetworkStream->SetReadTimeout(XN_SENSOR_CLIENT_READ_TIMEOUT); pStream = pNetworkStream; // create outgoing data packer (incoming is created by base class) m_pOutgoingPacker = XN_NEW(XnDataPacker, pNetworkStream, XN_SENSOR_SERVER_CONFIG_PACKER_SIZE); if (m_pOutgoingPacker == NULL) { XN_DELETE(pNetworkStream); xnOSCloseSocket(m_hSocket); return XN_STATUS_ALLOC_FAILED; } nRetVal = m_pOutgoingPacker->Init(); if (nRetVal != XN_STATUS_OK) { XN_DELETE(pNetworkStream); XN_DELETE(m_pOutgoingPacker); xnOSCloseSocket(m_hSocket); return nRetVal; } // send server a request to open the sensor nRetVal = m_pOutgoingPacker->WriteCustomData(XN_SENSOR_SERVER_MESSAGE_OPEN_SENSOR, strConnectionString, strlen(strConnectionString) + 1); if (nRetVal != XN_STATUS_OK) { XN_DELETE(pNetworkStream); XN_DELETE(m_pOutgoingPacker); xnOSCloseSocket(m_hSocket); return nRetVal; } return (XN_STATUS_OK); }
XnStatus SocketInConnection::ReadThreadProcImpl() { XnStatus nRetVal = XN_STATUS_OK; XN_SOCKET_HANDLE hSocket = NULL; XnBool bCanceled = FALSE; XnUInt32 nPacketBytesRead = 0; XnUInt32 nTotalBytesRead = 0; m_nConnectionStatus = ConnectSocket(hSocket, m_strIP, m_nPort); XN_IS_STATUS_OK_LOG_ERROR("Connect socket", m_nConnectionStatus); nRetVal = xnOSSetEvent(m_hConnectEvent); XN_IS_STATUS_OK_LOG_ERROR("Set connect event", nRetVal); while (!m_bStopReadThread) { //Fill buffer with received packets nTotalBytesRead = 0; for (XnUInt32 nPacket = 0; (nPacket < BUFFER_NUM_PACKETS); nPacket++) { nPacketBytesRead = m_nMaxPacketSize; m_nConnectionStatus = ReceivePacket(hSocket, m_pBuffer + nTotalBytesRead, nPacketBytesRead, bCanceled); if (m_nConnectionStatus != XN_STATUS_OK) { m_pDataDestination->HandleDisconnection(); xnLogError(XN_MASK_LINK, "Failed to receive packet: %s", xnGetStatusString(m_nConnectionStatus)); //XN_ASSERT(FALSE); return m_nConnectionStatus; } if (bCanceled) { //Ignore packet and exit loop break; } if (nTotalBytesRead == m_nBufferSize) { xnLogError(XN_MASK_LINK, "Read thread buffer overflowed :("); XN_ASSERT(FALSE); return XN_STATUS_INTERNAL_BUFFER_TOO_SMALL; } nTotalBytesRead += nPacketBytesRead; } if (m_pDataDestination != NULL) { //Send data in buffer to its destination. //Even if at this point the read thread should be stopped, first we send all the complete packets we got. if (nTotalBytesRead > 0) { m_pDataDestination->IncomingData(m_pBuffer, nTotalBytesRead); } } } nRetVal = xnOSCloseSocket(hSocket); if (nRetVal != XN_STATUS_OK) { xnLogWarning(XN_MASK_LINK, "Failed to close input data socket :("); XN_ASSERT(FALSE); } m_nConnectionStatus = XN_STATUS_OS_NETWORK_CONNECTION_CLOSED; return XN_STATUS_OK; }