예제 #1
0
        public static async Task <int> SendCompletelyAsync(this Socket socket, IList <ArraySegment <byte> > buffers,
                                                           SocketFlags socketFlags, CancellationToken token, SyncBufManager bufMgr)
        {
            token.ThrowIfCancellationRequested();
            var sent  = 0;
            var count = 0;

            for (var i = 0; i < buffers.Count; i++)
            {
                count += buffers[i].Count;
            }
            var copy = bufMgr.TakeBuffer(count);

            try
            {
                count = 0;
                for (var i = 0; i < buffers.Count; i++)
                {
                    ArraySegment <byte> arraySegment = buffers[i];
                    Buffer.BlockCopy(arraySegment.Array, arraySegment.Offset, copy, count, arraySegment.Count);
                    count += arraySegment.Count;
                }

                var bytes = await socket.SendCompletelyAsync(copy, count, socketFlags, token);

                sent += bytes;
                AppLogger.Debug($"SendCompletelyAsync:{sent},{buffers.Show()}");
                return(sent);
            }
            finally
            {
                bufMgr.ReturnBuffer(copy);
            }
        }
        private static async Task SendSampleData(int sampleTimeTick, SampleRateEnum rate, Socket socket, CancellationToken ctsToken)
        {
            byte size = 2 + ChannelCount * 3;
            var  buf  = bmgr.TakeBuffer(size);
            //_r.NextBytes(buf);
            var         passTimes = BrainDevState.PassTimeMs(rate, sampleTimeTick);
            const float max       = 4.5f / 24;

            buf[0] = (byte)DevCommandFuncId.StartStop;
            buf[1] = _brainState.SamplePacketOrder++;
            for (int i = 0; i < ChannelCount; i++)
            {
                var sampleValue = Math.Sin(passTimes * 2 / 1000f * Math.PI + i * simalatedDelta) * max;
                var(b0, b1, b2)    = BitDataConverter.ConvertTo(sampleValue, 4.5f, 24);
                buf[2 + i * 3]     = b0;
                buf[2 + 1 + i * 3] = b1;
                buf[2 + 2 + i * 3] = b2;
            }
            await SendWithHeadTail(socket, buf, size, ctsToken);

            bmgr.ReturnBuffer(buf);
        }
예제 #3
0
        //version 1 (byte version, uint devId, long startTick,BrainDevState state,byte[] MD5Hash)
        public static (byte, uint, long, BrainDevState, byte[]) ReadHeader(this FileStream fs,
                                                                           SyncBufManager bufferManager)
        {
            var buf   = bufferManager.TakeBuffer(CntStartIndex);
            var count = fs.Read(buf, 0, CntStartIndex);

            if (count < CntStartIndex)
            {
                throw new Exception("Invalid Sample Data File Format");
            }
            var version = buf[0];

            if (version != 1)
            {
                throw new Exception("not supported sample data format, only version 1 is supported");
            }
            var ind = 1;

            uint devId;
            long startTick;
            var  state = default(BrainDevState);

            unsafe
            {
                ReadPrimitive((byte *)&devId, sizeof(uint), buf, ref ind);
                ReadPrimitive((byte *)&startTick, sizeof(long), buf, ref ind);
                state.DevCode      = buf[ind++];
                state.ChannelCount = buf[ind++];
                state.Gain         = buf[ind++];
                state.SampleRate   = (SampleRateEnum)buf[ind++];
                state.TrapOption   = (TrapSettingEnum)buf[ind++];
                state.EnalbeFilter = buf[ind++] == 1;
            }
            var md5Buf = new byte[Md5Len];

            Buffer.BlockCopy(buf, ind, md5Buf, 0, Md5Len);
            bufferManager.ReturnBuffer(buf);
            return(version, devId, startTick, state, md5Buf);
        }
예제 #4
0
        public static IObservable <DisposableValue <ArraySegment <byte> > > ToFixedLenFrameObservable(this Socket socket,
                                                                                                      SyncBufManager bufferManager, IFixedLenFrameDecoder decoder)
        {
            return(Observable.Create <DisposableValue <ArraySegment <byte> > >(async(observer, token) =>
            {
                var receivedFlag = decoder.ReceivedFlags;
                var decoderLenByteCount = decoder.LenByteCount;
                var hc = 1 + decoderLenByteCount;
                var decoderHeader = decoder.Header;
                var decoderTail = decoder.Tail;
                var headerBuffer = new byte[hc];

                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        if (await socket.ReceiveCompletelyAsync(headerBuffer, hc, receivedFlag, token) != hc)
                        {
                            break;
                        }
                        if (headerBuffer[0] != decoderHeader)
                        {
                            AppLogger.Warning($"corruted packet: invalid frame header");
                            break;
                        }
                        var length = LengthBitConverter.FromByte(headerBuffer, 1, decoderLenByteCount) - 1;

                        var buffer = bufferManager.TakeBuffer(length);
                        if (await socket.ReceiveCompletelyAsync(buffer, length, receivedFlag, token) != length)
                        {
                            break;
                        }

                        var arraySegment = new ArraySegment <byte>(buffer, 0, length);
                        observer.OnNext(
                            new DisposableValue <ArraySegment <byte> >(arraySegment,
                                                                       Disposable.Create(() => bufferManager.ReturnBuffer(buffer))));

                        if (await socket.ReceiveAsync(headerBuffer, 0, 1, receivedFlag) == 0)
                        {
                            break;
                        }
                        if (headerBuffer[0] != decoderTail)
                        {
                            AppLogger.Warning($"corruted packet: invalid frame tail," + headerBuffer[0].Show());
                            break;
                        }
                    }

                    observer.OnCompleted();
                }
                catch (Exception error)
                {
                    observer.OnError(error);
                }
            }));
        }
예제 #5
0
        public static IObservable <DisposableValue <ArraySegment <byte> > > ToDynamicFrameObservable(this Socket socket,
                                                                                                     SyncBufManager bufferManager, IDynamicFrameDecoder decoder)
        {
            return(Observable.Create <DisposableValue <ArraySegment <byte> > >(async(observer, token) =>
            {
                try
                {
                    var state = decoder.InitState();
                    byte[] leftoverBuf = null;
                    //rider suggestion is buggy: this variable must declare outside the loop in the case when receive length is zero
                    int leftoverCount = 0;
                    while (!token.IsCancellationRequested)
                    {
                        byte[] bufferArray;
                        int startIdx;
                        if (leftoverBuf != null)
                        {
                            bufferArray = leftoverBuf;
                            startIdx = leftoverCount;
                            leftoverBuf = null;
                        }
                        else
                        {
                            bufferArray = bufferManager.TakeBuffer(decoder.BufferSize);
                            startIdx = 0;
                        }
                        var pair = await socket.ReceiveDynamicFrame(state, bufferArray, startIdx, decoder, token);
                        var receiveLen = pair.Item1;
                        leftoverCount = pair.Item2;
                        if (receiveLen == 0) //no data received, and leftoverCount should be zero
                        {
                            var dropFrameStrategy = decoder.CheckDropFrame(state, bufferArray, startIdx);
                            switch (dropFrameStrategy)
                            {
                            case DropFrameStrategyEnum.DropAndClose:
                                //reclaim buffer array
                                bufferManager.ReturnBuffer(bufferArray);
                                break;

                            case DropFrameStrategyEnum.DropAndRestart:
                                //reclaim buffer array
                                bufferManager.ReturnBuffer(bufferArray);
                                continue;

                            case DropFrameStrategyEnum.KeepAndContinue:
                                //keep last received data
                                leftoverBuf = bufferArray;
                                leftoverCount = startIdx;
                                continue;
                            }
                            if (dropFrameStrategy == DropFrameStrategyEnum.DropAndClose)
                            {
                                break;
                            }
                        }
                        if (receiveLen == -1) //overflow,TODO support extensible frame in future
                        {
                            //reclaim buffer array
                            bufferManager.ReturnBuffer(bufferArray);
                            break;
                        }
                        //copy leftover
                        if (leftoverCount > 0)
                        {
                            leftoverBuf = bufferManager.TakeBuffer(decoder.BufferSize);
                            Buffer.BlockCopy(bufferArray, receiveLen - leftoverCount, leftoverBuf, 0, leftoverCount);
                        }

                        var arraySegment = decoder.BuildFrame(state, bufferArray, receiveLen, leftoverCount);
                        observer.OnNext(
                            new DisposableValue <ArraySegment <byte> >(arraySegment,
                                                                       Disposable.Create(() => bufferManager.ReturnBuffer(bufferArray))));
                    }

                    observer.OnCompleted();

                    socket.Close();
                }
                catch (Exception error)
                {
                    observer.OnError(error);
                }
            }));
        }