/// <summary> /// Start or stop listening. /// </summary> /// <param name="state">if true : Start, otherwise, stop</param> public async void Listen(bool state = true) { if (state) { try { await StateSync.WaitAsync(1); if (Listener.IsListening) { return; } Listener.Start(); } finally { StateSync.Release(1); } try { while (true) { var context = await Listener.GetContextAsync(); ContextTask = Task.Run(() => OnRequest(context)); } } catch (Exception e) { OnListenError(e); } } else if (Listener.IsListening) { Listener.Stop(); } }
/// <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="filepath"></param> /// <param name="preBuffer"></param> /// <param name="postBuffer"></param> /// <param name="withLengthPrefixed"></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 ReadNextAsLong to true to do so.</remarks> /// <returns>A Task</returns> public async Task SendFileAsync(string filepath, byte[] preBuffer = null, byte[] postBuffer = null, bool withLengthPrefixed = true, bool preBufferIsBeforeLength = false) { try { await WriteSync.WaitAsync(1); if (preBuffer != null && preBufferIsBeforeLength) { await FinalStream.WriteAsync(preBuffer, 0, preBuffer.Length); } if (withLengthPrefixed) { await FinalStream.WriteAsync(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(new FileInfo(filepath).Length)), 0, 8); } if (preBuffer != null && preBufferIsBeforeLength == false) { await FinalStream.WriteAsync(preBuffer, 0, preBuffer.Length); } var buffer = new byte[FILEBUFFERSIZE]; using (var filefs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)) { int read = 0; while (true) { read = await filefs.ReadAsync(buffer, 0, FILEBUFFERSIZE); if (read == 0) { break; } await FinalStream.WriteAsync(buffer, 0, read); } } if (postBuffer != null) { await FinalStream.WriteAsync(postBuffer, 0, postBuffer.Length); } } finally { WriteSync.Release(1); } }
/// <summary> /// Start the server so that it accept connections, if it's not already started. /// </summary> public async void Start() { try { await StateSync.WaitAsync(1); if (isListening) { return; } isListening = true; } finally { StateSync.Release(1); } try { Listener.Start(Backlog); while (true) { Welcome(await Listener.AcceptTcpClientAsync()); } } catch { } finally { isListening = false; } }