/// <summary> /// The is the socket server listening thread. Creats a new client and /// starts a heartbeat client thread to implement the ping/pong protocol. /// </summary> protected void ListenForClients() { mRunning = true; try { while (mRunning) { //blocks until a client has connected to the server TcpClientProvider client = _tcpListener.AcceptTcpClient(); //create a thread to handle communication //with connected client Thread clientThread = new Thread(new ParameterizedThreadStart(HeartbeatClient)); clientThread.Start(client); clientThread.Join(); } } catch (Exception e) { Console.WriteLine("Execption occurred waiting for connection: " + e.Message); } finally { mRunning = false; _tcpListener.Stop(); } }
public WSClientProvider(int bufferSize = 4096, int blocks = 8) { clientProvider = new TcpClientProvider(bufferSize, blocks); clientProvider.DisconnectedCallback = new OnDisconnectedHandler(DisconnectedHandler); clientProvider.ReceivedOffsetCallback = new OnReceivedSegmentHandler(ReceivedHanlder); clientProvider.SentCallback = new OnSentHandler(SentHandler); }
/// <summary> /// Initializes a new instance of the <see cref="TcpSimpleClient"/> class. /// </summary> /// <param name="connectString">Connect string of the <see cref="TcpSimpleClient"/>. See <see cref="DefaultConnectionString"/> for format.</param> public TcpSimpleClient(string connectString) : base(TransportProtocol.Tcp, connectString) { m_tcpClient = new TcpClientProvider(); PayloadAware = DefaultPayloadAware; m_payloadMarker = Payload.DefaultMarker; m_payloadEndianOrder = EndianOrder.LittleEndian; NoDelay = DefaultNoDelay; }
public NetClientProvider(NetProviderType netProviderType) { NetProviderType = netProviderType; this.bufferSizeByConnection = 4096; this.maxConcurrentNumber = 8; if (netProviderType == NetProviderType.Tcp) { tcpClientProvider = new TcpClientProvider(bufferSizeByConnection, maxConcurrentNumber); } else if (netProviderType == NetProviderType.Udp) { udpClientProvider = new UdpClientProvider(bufferSizeByConnection, maxConcurrentNumber); } }
public NetClientProvider(ProviderType netProviderType = ProviderType.Tcp, int bufferSizeByConnection = 4096, int maxNumberOfConnections = 8) { NetProviderType = netProviderType; this.bufferSizeByConnection = bufferSizeByConnection; this.maxNumberOfConnections = maxNumberOfConnections; if (netProviderType == ProviderType.Tcp) { tcpClientProvider = new TcpClientProvider(bufferSizeByConnection, maxNumberOfConnections); } else if (netProviderType == ProviderType.Udp) { udpClientProvider = new UdpClientProvider(); } }
/// <summary> /// The heartbeat thread for a client. This thread receives data from a client, /// closes the socket when it fails, and handles communication timeouts when /// the client does not send a heartbeat within 2x the heartbeat frequency. /// /// When the heartbeat is not received, the client is assumed to be unresponsive /// and the connection is closed. Waits for one ping to be received before /// enforcing the timeout. /// </summary> /// <param name="client">The client we are communicating with.</param> protected void HeartbeatClient(object obj) { mActiveClients.AddCount(); TcpClientProvider client = (TcpClientProvider)obj; Stream clientStream = client.GetStream(); lock (mClients) { mClients.Add(clientStream); } // Send the current state and replay commands to new clients SendAllTo(clientStream); foreach (Tuple <DeviceCommand, string> tuple in _commandsToSendOnConnect) { _sendCommandToClient(clientStream, tuple.Item1, tuple.Item2); } byte[] assetMessage; foreach (IAsset a in _assetsToAdd) { assetMessage = _encoder.GetBytes(MakeAddAssetString(a)); WriteToClient(clientStream, assetMessage); } foreach (IAsset a in _assetsToRemove) { assetMessage = _encoder.GetBytes(MakeRemoveAssetString(a)); WriteToClient(clientStream, assetMessage); } List <Socket> readList = new List <Socket>(); bool heartbeatActive = false; byte[] message = new byte[4096]; int length = 0; try { while (mRunning && client.Connected) { int bytesRead = 0; try { readList.Clear(); readList.Add(client.Client); if (mHeartbeat > 0 && heartbeatActive) { Socket.Select(readList, null, null, mHeartbeat * 2000); } if (readList.Count == 0 && heartbeatActive) { Console.WriteLine("Heartbeat timed out, closing connection\n"); break; } //blocks until a client sends a message bytesRead = clientStream.Read(message, length, 4096 - length); } catch (Exception e) { //a socket error has occured Console.WriteLine("Heartbeat read exception: " + e.Message + "\n"); break; } if (bytesRead == 0) { //the client has disconnected from the server Console.WriteLine("No bytes were read from heartbeat thread"); break; } // See if we have a line int pos = length; length += bytesRead; int eol = 0; for (int i = pos; i < length; i++) { if (message[i] == '\n') { String line = _encoder.GetString(message, eol, i); if (Receive(clientStream, line)) { heartbeatActive = true; } eol = i + 1; } } // Remove the lines that have been processed. if (eol > 0) { length = length - eol; // Shift the message array to remove the lines. if (length > 0) { Array.Copy(message, eol, message, 0, length); } } } } catch (Exception e) { Console.WriteLine("Error during heartbeat: " + e.Message); } finally { try { lock (mClients) { mClients.Remove(clientStream); } client.Close(); } catch (Exception e) { Console.WriteLine("Error during heartbeat cleanup: " + e.Message); } mActiveClients.Signal(); } }