private void ConnectAsyncCallback(IAsyncResult state) { try { TcpClient client = _tcpListener.EndAcceptTcpClient(state); if (client.Connected) { client.NoDelay = true; TcpClientContext clientContext = new TcpClientContext(client); lock (_tcpClients) _tcpClients.Add(clientContext); foreach (KeyValuePair <Guid, Action <TcpClientContext, Boolean> > handler in _connectHandlers) { handler.Value(clientContext, true); } _logger.DebugFormat(ClientConnectedMessagedTemplate, clientContext.Id, ((IPEndPoint)client.Client.LocalEndPoint).Address); } } catch (Exception) { if (!_interruptRequested) { _logger.Error("An error occured during client connection"); } } _clientConnectEvent.Set(); }
private void ProcessClientReceiveSend(TcpClientContext client) { Byte[] receivedData = ReceiveImpl(client); client.Inactive = false; client.InactiveTimeMark = default(DateTime); if (receivedData.Length > 0) { test(receivedData, client); IList <Tuple <TcpClientHandlerInfo, Func <Byte[], TcpClientHandlerInfo, Byte[]> > > linkedHandlers = _clientsHandlers.Where(item => { //todo: umv: add special selection for AnyPort and AnyIp return(TcpClientHandlerSelector.Select(item.Item1, client)); }).ToList(); foreach (Tuple <TcpClientHandlerInfo, Func <Byte[], TcpClientHandlerInfo, Byte[]> > handler in linkedHandlers) { Byte[] dataForSend = handler.Item2(receivedData, handler.Item1); if (dataForSend != null && dataForSend.Length > 0) { SendImpl(client, dataForSend); } } } client.IsProcessing = false; OnPropertyChanged(); }
public static Boolean Select(TcpClientHandlerInfo clientHandlerInfo, TcpClientContext tcpClient) { if (String.Equals(GlobalDefs.AnyIpAddress, clientHandlerInfo.IpAddress) && GlobalDefs.AnyPort == clientHandlerInfo.Port) { return(true); } return(SelectByIpAddressComparison(clientHandlerInfo.IpAddress, tcpClient.Client) && SelectByPortComparison(clientHandlerInfo.Port, tcpClient.Client)); }
private void WriteAsyncCallback(IAsyncResult state) { TcpClientContext client = state.AsyncState as TcpClientContext; if (client == null) { throw new ApplicationException("state can't be null"); } client.Client.GetStream().EndWrite(state); client.WriteDataEvent.Set(); }
public void SendData(TcpClientHandlerInfo clientHandlerInfo, Byte[] data) { IList <TcpClientContext> selectedClients; lock (_tcpClients) { selectedClients = _tcpClients.Where(item => TcpClientHandlerSelector.Select(clientHandlerInfo, item)).ToList(); } foreach (TcpClientContext client in selectedClients) { TcpClientContext clientCopy = client; Task.Factory.StartNew(() => SendImpl(clientCopy, data)); } }
private void SendImpl(TcpClientContext client, Byte[] data) { try { _logger.DebugFormat(SendDataMessageTemplate, data.Length, client.Id, ((IPEndPoint)client.Client.Client.LocalEndPoint).Address); lock (client.WriteDataEvent) { client.WriteDataEvent.Reset(); NetworkStream netStream = client.Client.GetStream(); netStream.WriteTimeout = _config.WriteTimeout; netStream.BeginWrite(data, 0, data.Length, WriteAsyncCallback, client); client.WriteDataEvent.Wait(_config.WriteTimeout); } } catch (Exception) { //todo: umv: add error handling _logger.Error("An error occured during send data to client"); } }
private Byte[] ReceiveImpl(TcpClientContext client) { Byte[] buffer = new Byte[_config.ClientBufferSize]; client.BytesRead = 0; try { NetworkStream netStream = client.Client.GetStream(); netStream.ReadTimeout = _config.ReadTimeout; for (Int32 attempt = 0; attempt < _config.ClientReadAttempts; attempt++) { Boolean result = netStream.DataAvailable; while (result) { client.ReadDataEvent.Reset(); Array.Resize(ref buffer, buffer.Length + _config.ChunkSize); Int32 offset = client.BytesRead; Int32 size = _config.ChunkSize; netStream.BeginRead(buffer, offset, size, ReadAsyncCallback, client); client.ReadDataEvent.Wait(_config.ReadTimeout); result = netStream.DataAvailable; } } Array.Resize(ref buffer, client.BytesRead); if (client.BytesRead > 0) { _logger.DebugFormat(ReceivedDataMessageTemplate, client.BytesRead, client.Id, ((IPEndPoint)client.Client.Client.LocalEndPoint).Address); } } catch (Exception) { // todo: umv: add exception handling .... buffer = null; _logger.Error("Error occured during data read"); } return(buffer); }
private void updateUI(byte[] data, TcpClientContext cli) { IPEndPoint remote = ((IPEndPoint)cli.Client.Client.RemoteEndPoint); string ip = remote.Address.ToString(); string port = remote.Port.ToString(); string str = ToHexString(data); Action del = () => { this.Items3.Add( new SelectableViewModel { Code = 'R', Name = $"{ip}:{port}", Description = str, Food = "apple" } ); this.Items1.Add(cli); }; Dispatcher.Invoke(del); }
public void handleConnet(TcpClientContext c, Boolean b) { }
private void StartClientProcessing() { Int32 clientIndex = 0; while (!_interruptRequested) { // 1. waiting for connection ... if (_clientConnectingTask.IsCompleted || !(_clientConnectingTask.Status == TaskStatus.Running || _clientConnectingTask.Status == TaskStatus.WaitingToRun || _clientConnectingTask.Status == TaskStatus.WaitingForActivation || _clientConnectingTask.Status == TaskStatus.WaitingForChildrenToComplete)) { _clientConnectingTask = new Task(ClientConnectProcessing, new CancellationToken(_interruptRequested)); _clientConnectingTask.Start(); } /*if (_tcpClients.Count == 0) * { * }*/ if (_tcpClients.Count != 0) { // 2. handle clients ... (read + write) lock (_tcpClients) { if (clientIndex >= _tcpClients.Count) { clientIndex = 0; } for (Int32 clientCounter = clientIndex; clientCounter < _tcpClients.Count; clientCounter++) { if (CheckClientConnected(_tcpClients[clientCounter].Client) && !_tcpClients[clientCounter].IsProcessing) { TcpClientContext client = _tcpClients[clientCounter]; Int32 freeTaskIndex = -1; for (Int32 taskCounter = 0; taskCounter < _clientProcessingTasks.Count; taskCounter++) { if (_clientProcessingTasks[taskCounter] == null || _clientProcessingTasks[taskCounter].IsCompleted || (_clientProcessingTasks[taskCounter].Status != TaskStatus.Running && _clientProcessingTasks[taskCounter].Status != TaskStatus.WaitingToRun && _clientProcessingTasks[taskCounter].Status != TaskStatus.WaitingForActivation && _clientProcessingTasks[taskCounter].Status != TaskStatus.WaitingForChildrenToComplete)) { freeTaskIndex = taskCounter; break; } } if (freeTaskIndex >= 0) { _tcpClients[clientCounter].IsProcessing = true; _clientProcessingTasks[freeTaskIndex] = new Task(() => ProcessClientReceiveSend(client), new CancellationToken(_interruptRequested)); _clientProcessingTasks[freeTaskIndex].Start(); } else { clientIndex = clientCounter; } } } } // 3. check "disconnected" clients ... lock (_tcpClients) { IList <TcpClientContext> disoonnectedClients = _tcpClients.Where(client => !client.IsProcessing && !CheckClientConnected(client.Client)).ToList(); //todo: umv mark disconnected and check activity during some time .... foreach (TcpClientContext client in disoonnectedClients) { client.Inactive = true; if (client.InactiveTimeMark == default(DateTime)) { client.InactiveTimeMark = DateTime.Now; } else if (client.InactiveTimeMark.AddSeconds(_config.ClientInactivityTime) < DateTime.Now) { client.ReadDataEvent.Dispose(); client.WriteDataEvent.Dispose(); _logger.DebugFormat(ClientRemoveMessagedTemplate, client.Id, ((IPEndPoint)client.Client.Client.LocalEndPoint).Address); foreach (KeyValuePair <Guid, Action <TcpClientContext, Boolean> > handler in _connectHandlers) { handler.Value(client, false); } _tcpClients.Remove(client); } } } } } }
private async void ProcessClientAsync(TcpClient tcpClient, int clientIndex, CancellationToken cancellationToken) { var clientContext = new TcpClientContext(clientIndex, tcpClient); try { using (tcpClient) using (var networkStream = tcpClient.GetStream()) using (var packetStream = _packetStreamFactory.New()) { if (ClientConnectedEvent != null) { ClientConnectedEvent(clientContext, EventArgs.Empty); } Trace.TraceInformation("[Server] New client ({0}) connected", clientIndex); var buffer = new byte[4096]; while (!cancellationToken.IsCancellationRequested) { var timeoutTask = Task.Delay(TimeSpan.FromMilliseconds(_connectionTimeoutPeriod), cancellationToken); var bytesTask = networkStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); var completedTask = await Task.WhenAny(timeoutTask, bytesTask).ConfigureAwait(false); if (completedTask == timeoutTask) { var message = Encoding.UTF8.GetBytes("Client timed out"); await networkStream.WriteAsync(message, 0, message.Length, cancellationToken); } var bytes = bytesTask.Result; if (bytes == 0) { break; } if (MessageReceivedEvent == null) { continue; } var results = packetStream.ParseBytes(buffer.Take(bytes).ToArray()); if (results == null) { continue; } foreach (var result in results) { MessageReceivedEvent(clientContext, result); } } } } catch (Exception exception) { Trace.TraceWarning("[Server] Client ({0}) threw exception: {1}", clientIndex, exception.Message); } if (ClientDisconnectedEvent != null) { ClientDisconnectedEvent(clientContext, EventArgs.Empty); } Trace.TraceInformation("[Server] Client ({0}) disconnected", clientIndex); }
public void OnClientConnection(TcpClientContext context, Boolean connect) // connect true if client connected and false if disconnected { }