/// <summary> /// Overrideable. Called when a client is disconnected. /// </summary> /// <param name="client">The client</param> protected virtual void OnDisconnect(TcpClientInfo client) { if (Disconnected != null) { Disconnected(this, new TcpEventArgs(client)); } }
/// <summary> /// Overrideable. Called when an error occur while starting an SSL connection. /// </summary> /// <param name="client">The client</param> /// <param name="e">The error</param> protected virtual void OnSslError(TcpClientInfo client, Exception e) { if (SslError != null) { SslError(this, new TcpErrorEventArgs(client, e)); } }
/// <summary> /// Overrideable. Called when the maximum amount of clients is reached. /// </summary> /// <param name="client">The client</param> protected virtual void OnMaxClientsReach(TcpClientInfo client) { if (MaxClientsReached != null) { MaxClientsReached(this, new TcpEventArgs(client)); } }
/// <summary> /// Overrideable. Called when a fragment of a packet is received. /// </summary> /// <param name="client">The client</param> /// <param name="packet">The received packet</param> protected virtual void OnReceiveFragment(TcpClientInfo client, TcpFragment packet) { var ignoreFull = false; if (packet.Completed && client.ReadNextNotBuffered) { client.ReadNextNotBuffered = false; ignoreFull = true; } if (ReceivedFragment != null) { ReceivedFragment(this, new TcpFragmentReceivedEventArgs(client, packet)); } if (ignoreFull) { return; } else if ((ReceivedFull != null || ObtainFullPackets) && client.ReadNextNotBuffered == false) { if (packet.MemStream == null) { packet.MemStream = new MemoryStream(); } packet.WriteToStream(packet.MemStream); if (packet.Completed) { var data = packet.MemStream.ToArray(); OnReceiveFull(client, data); packet.MemStream.Dispose(); } } }
/// <summary> /// Overrideable. Called when a packet is completed and is desired to be received whole. /// </summary> /// <param name="client">The client</param> /// <param name="data">The whole packet</param> protected virtual void OnReceiveFull(TcpClientInfo client, byte[] data) { if (ReceivedFull != null) { ReceivedFull(this, new TcpReceivedEventArgs(client, data)); } }
private void Welcome(TcpClient client) { if (client == null) { return; } Task.Run(() => { try { var cinfo = new TcpClientInfo(this, client, HandlerType.Server, ReadTimeout, BufferSize); if (Clients.Count >= MaxClients) { OnMaxClientsReach(cinfo); client.Close(); } else if (Clients.TryAdd(client, cinfo)) { cinfo.EnableSsl = SSLServerCertificate != null; cinfo.SSLServerCertificate = SSLServerCertificate; cinfo.IsLengthInOneFrame = IsLengthInOneFrame; cinfo.StartReceive(); OnConnect(cinfo); } else { client.Close(); } } catch { client.Close(); throw; } }); }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="info">The client</param> /// <param name="packet">The packet</param> /// <param name="innerEx">the inner exception</param> public void ReportPacketFragment(TcpClientInfo info, TcpFragment packet, ref Exception innerEx) { try { OnReceiveFragment(packet); } catch (Exception e) { innerEx = e; throw e; } }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="info">The disconnected client</param> /// <param name="innerEx">the inner exception</param> public void ReportDisconnection(TcpClientInfo info, ref Exception innerEx) { try { Disposed = true; OnDisconnect(); } catch (Exception e) { innerEx = e; throw e; } }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="client">The disconnected client</param> /// <param name="innerEx">the inner exception</param> public void ReportDisconnection(TcpClientInfo client, ref Exception innerEx) { try { Clients.TryRemove(client.Client, out client); if (client != null) { OnDisconnect(client); } } catch (Exception e) { innerEx = e; throw e; } }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="client">The client</param> /// <param name="e">The error</param> public void ReportReceiveError(TcpClientInfo client, Exception e) { OnReceiveError(client, e); }
/// <summary> /// Create the TcpEventArgs. /// </summary> /// <param name="info">The client</param> /// <param name="accepted">The acceptance state</param> public TcpSslValidateEventArgs(TcpClientInfo info, bool?accepted = null) { Client = info; Accepted = accepted; }
/// <summary> /// Disconnect the given client. /// </summary> /// <param name="client">The client</param> public void DisconnectClient(TcpClientInfo client) { client.Disconnect(); }
/// <summary> /// Send a whole file, given a prebuffer and a postbuffer, and if the 8 bytes length is sent before the real message. /// </summary> /// <param name="client">The receiving client</param> /// <param name="filepath">The path to the file</param> /// <param name="preBuffer">A prefixed buffer</param> /// <param name="postBuffer">A suffixed buffer</param> /// <param name="withLengthPrefixed">if the 4 bytes length is sent before the real message</param> /// <param name="preBufferIsBeforeLength">Weither the prebuffer is placed before the length prefix (if applicable)</param> /// <returns>A Task</returns> /// <remarks>If withLengthPrefixed is true, it's important for the receiving end to know that he is receiving a longer a 8 bytes length prefix. For the receiving end and within this class, you can set 'InfoHandler.ReadNextAsLong' to true to do so.</remarks> public async Task SendFileAsync(TcpClientInfo client, string filepath, byte[] preBuffer = null, byte[] postBuffer = null, bool withLengthPrefixed = true, bool preBufferIsBeforeLength = false) { await client.SendFileAsync(filepath, preBuffer, postBuffer, withLengthPrefixed, preBufferIsBeforeLength); }
/// <summary> /// Send a whole file to a chosen client, given a prebuffer and a postbuffer, and if the 8 bytes length is sent before the real message. /// </summary> /// <param name="client">The receiving client</param> /// <param name="filepath">The path to the file</param> /// <param name="preBuffer">A prefixed buffer</param> /// <param name="postBuffer">A suffixed buffer</param> /// <param name="withLengthPrefixed">if the 4 bytes length is sent before the real message</param> /// <param name="preBufferIsBeforeLength">Weither the prebuffer is placed before the length prefix (if applicable)</param> /// <remarks>If withLengthPrefixed is true, it's important for the receiving end to know that he is receiving a longer a 8 bytes length prefix. For the receiving end and within this class, you can set 'InfoHandler.ReadNextAsLong' to true to do so.</remarks> public void SendFile(TcpClientInfo client, string filepath, byte[] preBuffer = null, byte[] postBuffer = null, bool withLengthPrefixed = true, bool preBufferIsBeforeLength = false) { client.SendFile(filepath, preBuffer, postBuffer, withLengthPrefixed, preBufferIsBeforeLength); }
/// <summary> /// Send an array of bytes to the chosen client, given an offset, length and if the 4 bytes length is sent before the real message. /// </summary> /// <param name="client">The receiving client</param> /// <param name="data">The data to send</param> /// <param name="offset">The offset of the data</param> /// <param name="count">The length to read from the data (if null, will take full length)</param> /// <param name="withLengthPrefixed">if the 4 bytes length is sent before the real message</param> /// <returns>A Task</returns> public async Task SendAsync(TcpClientInfo client, byte[] data, int offset = 0, int?count = null, bool withLengthPrefixed = true) { await client.SendAsync(data, offset, count, withLengthPrefixed); }
/// <summary> /// Send an array of bytes to the chosen client, given an offset, length and if the 4 bytes length is sent before the real message. /// </summary> /// <param name="client">The receiving client</param> /// <param name="data">The data to send</param> /// <param name="offset">The offset of the data</param> /// <param name="count">The length to read from the data (if null, will take full length)</param> /// <param name="withLengthPrefixed">if the 4 bytes length is sent before the real message</param> public void Send(TcpClientInfo client, byte[] data, int offset = 0, int?count = null, bool withLengthPrefixed = true) { client.Send(data, offset, count, withLengthPrefixed); }
/// <summary> /// Create the TcpErrorEventArgs. /// </summary> /// <param name="info">The client</param> /// <param name="e">The error</param> public TcpErrorEventArgs(TcpClientInfo info, Exception e) { Client = info; Error = e; }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="client">The client</param> /// <param name="e">The error</param> public void ReportSslError(TcpClientInfo client, Exception e) { OnSslError(client, e); }
private void RestartSocket() { Client = new TcpClient(); InfoHandler = new TcpClientInfo(this, Client, HandlerType.Client, 0, BufferSize); Disposed = false; }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="info">The client</param> /// <param name="e">The error</param> public void ReportReceiveError(TcpClientInfo info, Exception e) { OnReceiveError(e); }
/// <summary> /// Create the TcpReceivedEventArgs. /// </summary> /// <param name="info">The client</param> /// <param name="data">The full data</param> public TcpReceivedEventArgs(TcpClientInfo info, byte[] data) { Client = info; Data = data; }
/// <summary> /// Create the TcpEventArgs. /// </summary> /// <param name="info">The client</param> public TcpEventArgs(TcpClientInfo info) { Client = info; }
/// <summary> /// Not much useful outside internal callings. /// </summary> /// <param name="info">The client</param> /// <param name="e">The error</param> public void ReportSslError(TcpClientInfo info, Exception e) { OnSslError(e); }
/// <summary> /// Create the TcpFragmentReceivedEventArgs. /// </summary> /// <param name="info">The client</param> /// <param name="packet">The packet fragment received</param> public TcpFragmentReceivedEventArgs(TcpClientInfo info, TcpFragment packet) { Client = info; Packet = packet; }