/// <summary> /// Replaces the old socket from <see cref="m_socket_conn"/> /// with the current socket or adds it, if it does not exist. /// </summary> /// <param name="stNew">The current socket</param> protected void ReplaceSocket(stDeviceSocket stNew) { try { if (!m_socket_conn.ContainsKey(stNew.deviceid)) { // device not exist, lets add it m_socket_conn.Add(stNew.deviceid, stNew); } else { // device exist, find the old thread and kill it, and replace it stDeviceSocket stOld = m_socket_conn[stNew.deviceid]; // do nothing if device is comming from same thread if (stNew.thread.ManagedThreadId == stOld.thread.ManagedThreadId) { return; } // explicitly close the client socket if (stOld.thread.IsAlive && stOld.tcpClient.Connected) { stOld.tcpClient.Close(); } // replace with current thread m_socket_conn[stNew.deviceid] = stNew; } } catch (Exception ex) { LogManager.LogErrorLine("Exception ReplaceSocket: {0}", ex.Message); } }
protected override void HandleDeviceThread(object obj) { byte[] data = new byte[SocketParserConstants.MAX_SIZE_READ_PACKET_BUFFER]; TcpClient remclient = (TcpClient)obj; NetworkStream netstream = remclient.GetStream(); remclient.ReceiveTimeout = SocketParserConstants.READ_PACKET_TIMEOUT_SHORT; LogManager.LogInfoLine("Client Connected. Active Connections = {0}", ++m_nConnections); // main loop to service the client while (netstream.CanRead) { try { // clear buffer and read from network packet [blocking call] Array.Clear(data, 0, data.Length); int recv = netstream.Read(data, 0, data.Length); // close socket if nothing was received if (recv <= 0) { LogManager.LogInfoLine("Socket Closed."); break; } // now that we have received initial data from device, let's increase max time-out remclient.ReceiveTimeout = SocketParserConstants.READ_PACKET_TIMEOUT_LONG; // handle data packet, log any and all data sent to server if (this.OnRead(data, recv, netstream) == false || recv > SocketParserConstants.MAX_SIZE_DATAGRAM) { continue; } /* * // check if client issued a closing request, if so, close client socket and thread * if (IsClientClosing(data)) * { * LogManager.LogInfoLine("Client Closed."); * break; * } * */ // we'll need to replace the socket/close the old thread long devid = 0; if (this.OnGetDeviceId(data, out devid)) { stDeviceSocket stobj = new stDeviceSocket { deviceid = devid, thread = Thread.CurrentThread, tcpClient = remclient }; // replace socket, and insert data into tracker log string strerr = string.Empty; lock (_cs_mutex) { this.ReplaceSocket(stobj); if (SocketSQL.Instance.InsertToDatabase(_deviceModel, data, recv, out strerr)) { continue; } if (SocketSQL.Instance.InsertToDatabase(_deviceModel, data, recv, out strerr)) { continue; } if (SocketSQL.Instance.InsertToDatabase(_deviceModel, data, recv, out strerr)) { continue; } } // end critical section // 3x tries and we failed to insert into TrackerLog, lets log it LogManager.LogErrorLine("MySqlInsertError: {0}", strerr); } } catch (IOException) { LogManager.LogInfoLine("Socket replaced or client timed-out."); break; } catch (SocketException ex) { LogManager.LogErrorLine("HandleDeviceThread - SocketException: {0}", ex.Message); break; } catch (Exception ex) { LogManager.LogErrorLine("HandleDeviceThread - Exception: {0}", ex.Message); break; } } netstream.Close(); remclient.Close(); LogManager.LogInfoLine("Client Disconnected. Active Connections = {0}", --m_nConnections); }