コード例 #1
0
        /// <deprecated>
        /// Not used. For reference only.
        /// </deprecated>
        private async void StartPolling1()
        {
            while (true)
            {
                var readResult = await pipeReader.ReadAsync().ConfigureAwait(false);

                ReadOnlySequence <byte> buffer   = readResult.Buffer;
                SequencePosition?       position = buffer.Start;
                var remainingBytes = buffer.Length;
                var writeResult    = (byte)0;
                while (remainingBytes > 0)
                {
                    while (localStackByteCount == 0)
                    {
                        await _tun.executeLwipTask(() => _socket.Output());

                        await localStackBufLock.WaitAsync().ConfigureAwait(false);
                    }
                    var bytesToWriteCount = Math.Min(remainingBytes, localStackByteCount);
                    var chunk             = buffer.Slice(position.Value, bytesToWriteCount);
                    var arr  = chunk.ToArray();
                    var more = remainingBytes != bytesToWriteCount;
                    writeResult = await _tun.executeLwipTask(() => _socket.Send(arr, more));

                    if (writeResult != 0)
                    {
                        OnError?.Invoke(this, writeResult);
                        pipeReader.Complete();
                        return;
                    }
                    remainingBytes -= bytesToWriteCount;
                    position        = buffer.GetPosition(bytesToWriteCount, position.Value);
                    Interlocked.Add(ref localStackByteCount, (int)-bytesToWriteCount);
                }
                pipeReader.AdvanceTo(position.Value, position.Value);
                await _tun.executeLwipTask(() => _socket.Output());

                if (readResult.IsCanceled || readResult.IsCompleted || writeResult != 0)
                {
                    break;
                }
            }
            pipeReader.Complete();
            await _tun.executeLwipTask(() => _socket.Close());

            Debug.WriteLine($"{TcpSocket.ConnectionCount()} connections now");
            LocalDisconnected = true;
            OnFinished(this);
            CheckShutdown();
        }
コード例 #2
0
        private async ValueTask <bool> PushOne()
        {
            var readResult = await inboundReader.ReadAsync(pushCancelSource.Token).ConfigureAwait(false);

            var  buffer      = readResult.Buffer;
            byte writeResult = 0;
            var  start       = buffer.Start;

            // A buffer may consist of several Memory<byte> chunks,
            // read one of them at a time.
            // Note that a chunk may be large, thus must be splitted into smaller chunks.
            while (buffer.TryGet(ref start, out var remainingChunk))
            {
                while (remainingChunk.Length > 0)
                {
                    // Wait until there is enough space in the stack
                    while (localStackAvailableByteCount <= 1600)
                    {
                        await localStackBufLock.WaitAsync(pushCancelSource.Token).ConfigureAwait(false);
                    }
                    var len   = Math.Min(localStackAvailableByteCount, remainingChunk.Length);
                    var chunk = remainingChunk.Slice(0, len);
                    remainingChunk = remainingChunk.Slice(len);
                    var more = true;// remainingChunk.Length != 0 || !start.Equals(buffer.End);
                    using (var dataHandle = chunk.Pin())
                    {
                        writeResult = await SendToSocket(dataHandle, (ushort)chunk.Length, more).ConfigureAwait(false);

                        while (writeResult == 255)
                        {
                            if (!await(localStackBufLock?.WaitAsync(10000, pushCancelSource.Token).ConfigureAwait(false) ?? Task.FromResult(false).ConfigureAwait(false)))
                            {
                                DebugLogger.Log("Local write timeout");
                                break;
                            }
                            writeResult = await SendToSocket(dataHandle, (ushort)chunk.Length, more).ConfigureAwait(false);
                        }
                    }
                    if (writeResult != 0)
                    {
                        DebugLogger.Log("Error from writing to local socket:" + writeResult.ToString());
                        // TODO: distinguish write error with general socket error
                        Socket_SocketError(_socket, writeResult);
                        return(false);
                    }
                    Interlocked.Add(ref localStackAvailableByteCount, -chunk.Length);
                    Interlocked.Add(ref localPendingByteCount, chunk.Length);
                    await _tun.executeLwipTask(() => _socket.Output());
                }
            }
            inboundReader.AdvanceTo(buffer.End);
            //await _tun.executeLwipTask(() => _socket.Output());

            if (readResult.IsCanceled || readResult.IsCompleted || writeResult != 0 || pushCancelSource.IsCancellationRequested)
            {
                return(false);
            }
            return(true);
        }