/// <summary> /// Processes to send a <see cref="Message"/> using the specified <see cref="SocketAsyncEventArgs"/>. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessSend(SocketAsyncEventArgs AsyncEvent) { NetworkToken Token = (NetworkToken)AsyncEvent.UserToken; if (AsyncEvent.SocketError == SocketError.Success) { if (AsyncEvent.Count > AsyncEvent.BytesTransferred) { int Offset = AsyncEvent.Offset + AsyncEvent.BytesTransferred; if (Token.IsConnected) { AsyncEvent.SetBuffer(Offset, AsyncEvent.Buffer.Length - Offset); if (!Token.Socket.SendAsync(AsyncEvent)) { NetworkTcp.ProcessSend(AsyncEvent); } return; } NetworkTcp.Disconnect(Token.AsyncEvent); } } else { NetworkTcp.Disconnect(Token.AsyncEvent); } NetworkTcp.OnSendCompleted(null, AsyncEvent); }
/// <summary> /// Closes the specified client's socket. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> public static void Disconnect(SocketAsyncEventArgs AsyncEvent) { NetworkToken Token = AsyncEvent.UserToken as NetworkToken; Logging.Info(typeof(NetworkToken), "Disconnect(AsyncEvent)."); if (Token.IsAborting) { return; } Token.IsAborting = true; if (Token.Device != null) { Token.Device.State = State.Disconnected; if (Token.IsConnected) { try { Token.Socket.Shutdown(SocketShutdown.Both); } catch (Exception Exception) { Logging.Warning(typeof(NetworkTcp), Exception.GetType().Name + " thrown at Disconnect(" + AsyncEvent.RemoteEndPoint + ")."); } } Token.Socket.Close(); } NetworkTcp.ReadPool.Enqueue(AsyncEvent); }
/// <summary> /// Starts to receive data from remote host. /// </summary> public static void StartReceive(NetworkToken Token) { if (!Token.Socket.ReceiveAsync(Token.AsyncEvent)) { NetworkTcp.ProcessReceive(Token.AsyncEvent); } }
/// <summary> /// Accept the new client and store it in memory. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessAccept(SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.AcceptSocket.Connected) { string IpAddress = ((IPEndPoint)AsyncEvent.AcceptSocket.RemoteEndPoint).Address.ToString(); if (IpAddress.StartsWith("192.168.")) { SocketAsyncEventArgs ReadEvent = NetworkTcp.ReadPool.Dequeue(); if (ReadEvent != null) { NetworkToken Token = new NetworkToken(ReadEvent, AsyncEvent.AcceptSocket); Device Device = new Device(Token); Devices.Add(Device); if (!Token.Socket.ReceiveAsync(ReadEvent)) { NetworkTcp.ProcessReceive(ReadEvent); } } else { Logging.Warning(typeof(NetworkTcp), "Server is full, new connections cannot be accepted."); } } } NetworkTcp.StartAccept(AsyncEvent); }
/// <summary> /// Connets the specified token to the remote host. /// </summary> public static bool StartConnect(string Host, out NetworkToken Token) { Socket Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Socket.Blocking = false; Socket.NoDelay = true; var ConnectEvent = new SocketAsyncEventArgs(); ConnectEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339); ManualResetEventSlim Waiter = new ManualResetEventSlim(); ConnectEvent.Completed += NetworkTcp.OnConnectCompleted; ConnectEvent.UserToken = Waiter; if (!Socket.ConnectAsync(ConnectEvent)) { NetworkTcp.OnConnectCompleted(Socket, ConnectEvent); } if (Waiter.Wait(10000)) { var AsyncEvent = NetworkTcp.ReadPool.Dequeue(); if (AsyncEvent != null) { Token = new NetworkToken(AsyncEvent, ConnectEvent.ConnectSocket); Token.AsyncEvent.AcceptSocket = null; Token.AsyncEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339); if (!Token.Socket.ReceiveAsync(Token.AsyncEvent)) { NetworkTcp.ProcessReceive(Token.AsyncEvent); } return(true); } else { Logging.Info(typeof(NetworkTcp), "AsyncEvent == null at StartConnect()."); } } else { Logging.Info(typeof(NetworkTcp), "Waiter.Wait(10000) != true at StartConnect()."); } Token = null; return(false); }
/// <summary> /// Receives data from the specified client. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessReceive(SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.BytesTransferred == 0) { NetworkTcp.Disconnect(AsyncEvent); } if (AsyncEvent.SocketError != SocketError.Success) { NetworkTcp.Disconnect(AsyncEvent); } NetworkToken Token = (NetworkToken)AsyncEvent.UserToken; if (Token.IsConnected) { Token.AddData(); try { if (Token.Socket.Available == 0) { Token.Process(); } if (Token.IsFailing == false) { if (!Token.Socket.ReceiveAsync(AsyncEvent)) { NetworkTcp.ProcessReceive(AsyncEvent); } } else { NetworkTcp.Disconnect(AsyncEvent); } } catch (Exception Exception) { Logging.Warning(typeof(NetworkTcp), Exception.GetType().Name + " thrown at ProcessReceive(" + AsyncEvent.RemoteEndPoint + ")."); NetworkTcp.Disconnect(AsyncEvent); } } else { NetworkTcp.Disconnect(AsyncEvent); } }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="Buffer">The buffer.</param> /// <param name="Token">The token.</param> public static void Send(byte[] Buffer, NetworkToken Token) { if (Buffer == null) { throw new ArgumentNullException(nameof(Message), "Buffer == null at Send(Buffer, Token)."); } if (Token == null) { throw new ArgumentNullException(nameof(Token), "Token == null at Send(Buffer, Token)."); } if (Token.IsConnected) { SocketAsyncEventArgs WriteEvent = NetworkTcp.WritePool.Dequeue(); if (WriteEvent == null) { WriteEvent = new SocketAsyncEventArgs { DisconnectReuseSocket = false }; } WriteEvent.SetBuffer(Buffer, 0, Buffer.Length); WriteEvent.AcceptSocket = Token.Socket; WriteEvent.RemoteEndPoint = Token.Socket.RemoteEndPoint; WriteEvent.UserToken = Token; if (!Token.Socket.SendAsync(WriteEvent)) { NetworkTcp.ProcessSend(WriteEvent); } } else { NetworkTcp.Disconnect(Token.AsyncEvent); } }