コード例 #1
0
        /// <summary>
        /// 创建命令输入数据
        /// </summary>
        /// <param name="buildInfo">TCP 客户端创建命令参数</param>
        /// <returns>下一个命令</returns>
        internal unsafe override TcpServer.ClientCommand.CommandBase Build(ref TcpServer.SenderBuildInfo buildInfo)
        {
            UnmanagedStream stream = Socket.OutputSerializer.Stream;

            if ((buildInfo.SendBufferSize - stream.ByteSize) >= sizeof(int))
            {
                *(int *)stream.CurrentData = CommandInfo.Command | (int)(uint)(CommandInfo.CommandFlags | TcpServer.CommandFlags.NullData);
                stream.ByteSize           += sizeof(int);
                return(LinkNext);
            }
            buildInfo.isFullSend = 1;
            return(this);
        }
コード例 #2
0
        /// <summary>
        /// 创建输出信息
        /// </summary>
        /// <param name="sender">TCP 服务套接字数据发送</param>
        /// <param name="buildInfo">输出创建参数</param>
        internal unsafe override OutputLink Build(ServerSocketSenderBase sender, ref TcpServer.SenderBuildInfo buildInfo)
        {
            UnmanagedStream stream = sender.OutputSerializer.Stream;

            if ((buildInfo.SendBufferSize - stream.ByteSize) >= sizeof(int))
            {
                OutputLink nextBuild = LinkNext;
                *(int *)stream.CurrentData = (byte)ReturnType;
                LinkNext         = null;
                stream.ByteSize += sizeof(int);
                AutoCSer.Threading.RingPool <ReturnTypeOutput> .Default.PushNotNull(this);

                return(nextBuild);
            }
            buildInfo.isFullSend = 1;
            return(this);
        }
コード例 #3
0
        /// <summary>
        /// 创建输出信息
        /// </summary>
        /// <param name="sender">TCP 服务套接字数据发送</param>
        /// <param name="buildInfo">输出创建参数</param>
        internal override OutputLink Build(TcpServer.ServerSocketSenderBase sender, ref TcpServer.SenderBuildInfo buildInfo)
        {
            UnmanagedStream stream = sender.OutputSerializer.Stream;

            if (stream.ByteSize == 0 || (buildInfo.SendBufferSize - stream.ByteSize) >= outputInfo.MaxDataSize)
            {
                ulong      markData     = sender.ServerSocket.MarkData;
                int        streamLength = stream.ByteSize;
                OutputLink nextBuild    = LinkNext;
                stream.PrepLength(sizeof(int) * 2);
                stream.ByteSize += sizeof(int);
                if (outputInfo.IsJsonSerialize == 0)
                {
                    sender.Serialize(outputInfo, ref outputParameter);
                }
                else
                {
                    sender.JsonSerialize(ref outputParameter);
                }
                int   dataLength = stream.ByteSize - streamLength - sizeof(int);
                byte *dataStart  = stream.Data.Byte + streamLength;
                *(int *)dataStart = dataLength + OutputDataSize;
                if (markData != 0)
                {
                    TcpServer.CommandBase.Mark(dataStart + sizeof(int), markData, dataLength);
                }
                outputInfo.CheckMaxDataSize(Math.Max(dataLength + sizeof(int), stream.LastPrepSize - streamLength));
                LinkNext        = null;
                outputParameter = default(outputParameterType);
                AutoCSer.Threading.RingPool <Output <outputParameterType> > .Default.PushNotNull(this);

                return(nextBuild);
            }
            buildInfo.isFullSend = 1;
            return(this);
        }
コード例 #4
0
 /// <summary>
 /// 发送数据
 /// </summary>
 internal unsafe void BuildOutput()
 {
     if (IsSocket)
     {
         TcpStreamServer.ServerOutput.OutputLink head = null, end;
         TcpServer.SenderBuildInfo buildInfo = new TcpServer.SenderBuildInfo { SendBufferSize = Server.SendBufferPool.Size, IsClientAwaiter = Server.Attribute.IsClientAwaiter };
         UnmanagedStream outputStream;
         try
         {
             if (Buffer.Buffer == null) Server.SendBufferPool.Get(ref Buffer);
             if (OutputSerializer == null) outputStream = (OutputSerializer = BinarySerialize.Serializer.YieldPool.Default.Pop() ?? new BinarySerialize.Serializer()).SetTcpServer();
             else outputStream = OutputSerializer.Stream;
             int outputSleep = OutputSleep, currentOutputSleep;
             do
             {
                 buildInfo.IsNewBuffer = 0;
                 fixed (byte* dataFixed = Buffer.Buffer)
                 {
                     byte* start = dataFixed + Buffer.StartIndex;
                     STREAM:
                     using (outputStream)
                     {
                         if (outputStream.Data.Byte != start) outputStream.Reset(start, Buffer.Length);
                         buildInfo.Clear();
                         outputStream.ByteSize = 0;
                         currentOutputSleep = outputSleep;
                         if ((head = Outputs.GetClear(out end)) == null) goto CHECK;
                         LOOP:
                         do
                         {
                             head = head.Build(this, ref buildInfo);
                             if (buildInfo.IsSend != 0 || !ServerSocket.IsVerifyMethod)
                             {
                                 if (head != null) Outputs.PushHead(ref head, end);
                                 goto SEND;
                             }
                         }
                         while (head != null);
                         if (!Outputs.IsEmpty)
                         {
                             head = Outputs.GetClear(out end);
                             goto LOOP;
                         }
                         CHECK:
                         if (currentOutputSleep >= 0)
                         {
                             Thread.Sleep(currentOutputSleep);
                             if (!Outputs.IsEmpty)
                             {
                                 head = Outputs.GetClear(out end);
                                 currentOutputSleep = 0;
                                 goto LOOP;
                             }
                         }
                         if (outputStream.ByteSize == 0)
                         {
                             outputStream.Dispose();
                             goto END;
                         }
                         SEND:
                         buildInfo.IsNewBuffer = setSendData(start);
                     }
                     switch (send())
                     {
                         case TcpOpenServer.SendState.Asynchronous: return;
                         case TcpOpenServer.SendState.Error: buildInfo.IsError = true; return;
                     }
                     if (!Outputs.IsEmpty)
                     {
                         if (buildInfo.IsNewBuffer == 0) goto STREAM;
                         goto FIXEDEND;
                     }
                     END:
                     //IsOutput = 0;
                     if (IsSocket)
                     {
                         Interlocked.Exchange(ref IsOutput, 0);
                         if (!Outputs.IsEmpty)
                         {
                             if (Interlocked.CompareExchange(ref IsOutput, 1, 0) == 0)
                             {
                                 if (buildInfo.IsNewBuffer == 0) goto STREAM;
                                 goto FIXEDEND;
                             }
                         }
                         else if (!IsSocket && Interlocked.CompareExchange(ref IsOutput, 1, 0) == 0) buildInfo.IsClose = true;
                     }
                     else buildInfo.IsClose = true;
                     return;
                     FIXEDEND:;
                 }
             }
             while (buildInfo.IsNewBuffer != 0);
         }
         catch (Exception error)
         {
             Server.Log.add(AutoCSer.Log.LogType.Error, error);
             buildInfo.IsError = true;
         }
         finally
         {
             if (buildInfo.IsError | buildInfo.IsClose)
             {
                 if (buildInfo.IsError) closeSocket();
                 else close();
                 TcpStreamServer.ServerOutput.OutputLink.CancelLink(head);
             }
         }
     }
     else close();
 }
コード例 #5
0
        /// <summary>
        /// 发送数据
        /// </summary>
        internal unsafe void BuildOutput()
        {
            if (IsSocket)
            {
                TcpStreamServer.ServerOutput.OutputLink head = null, end;
                TcpServer.SenderBuildInfo buildInfo = new TcpServer.SenderBuildInfo {
                    SendBufferSize = Server.SendBufferPool.Size, IsClientAwaiter = Server.Attribute.IsClientAwaiter
                };
                UnmanagedStream outputStream;
                SocketError     socketError;
                try
                {
                    if (Buffer.Buffer == null)
                    {
                        Server.SendBufferPool.Get(ref Buffer);
                    }
                    if (OutputSerializer == null)
                    {
                        outputStream = (OutputSerializer = BinarySerialize.Serializer.YieldPool.Default.Pop() ?? new BinarySerialize.Serializer()).SetTcpServer();
                    }
                    else
                    {
                        outputStream = OutputSerializer.Stream;
                    }
                    int outputSleep = OutputSleep, currentOutputSleep;
                    do
                    {
                        buildInfo.IsNewBuffer = 0;
                        fixed(byte *dataFixed = Buffer.Buffer)
                        {
                            byte *start = dataFixed + Buffer.StartIndex;

                            currentOutputSleep = outputSleep;
STREAM:
                            using (outputStream)
                            {
RESET:
                                if (outputStream.Data.Byte != start)
                                {
                                    outputStream.Reset(start, Buffer.Length);
                                }
                                buildInfo.Clear();
                                outputStream.ByteSize = 0;
                                if ((head = Outputs.GetClear(out end)) == null)
                                {
                                    if (currentOutputSleep < 0)
                                    {
                                        goto CHECK;
                                    }
                                    Thread.Sleep(currentOutputSleep);
                                    if (Outputs.IsEmpty)
                                    {
                                        goto CHECK;
                                    }
                                    head = Outputs.GetClear(out end);
                                    currentOutputSleep = 0;
                                }
LOOP:
                                do
                                {
                                    head = head.Build(this, ref buildInfo);
                                    if (buildInfo.IsSend != 0 || !ServerSocket.IsVerifyMethod)
                                    {
                                        goto SETDATA;
                                    }
                                }while (head != null);
                                if (!Outputs.IsEmpty)
                                {
                                    head = Outputs.GetClear(out end);
                                    goto LOOP;
                                }
                                if (!buildInfo.IsClientAwaiter)
                                {
                                    if (currentOutputSleep >= 0)
                                    {
                                        Thread.Sleep(currentOutputSleep);
                                        if (!Outputs.IsEmpty)
                                        {
                                            head = Outputs.GetClear(out end);
                                            currentOutputSleep = 0;
                                            goto LOOP;
                                        }
                                    }
                                }
                                else
                                {
                                    if (currentOutputSleep == int.MinValue)
                                    {
                                        currentOutputSleep = outputSleep;
                                    }
                                    if (currentOutputSleep >= 0)
                                    {
                                        Thread.Sleep(currentOutputSleep);
                                    }
                                    else
                                    {
                                        AutoCSer.Threading.ThreadYield.YieldOnly();
                                    }
                                    if (!Outputs.IsEmpty)
                                    {
                                        head = Outputs.GetClear(out end);
                                        currentOutputSleep = 0;
                                        goto LOOP;
                                    }
                                }
CHECK:
                                if (outputStream.ByteSize == 0)
                                {
                                    goto DISPOSE;
                                }
SETDATA:
                                buildInfo.IsNewBuffer = setSendData(start);
SEND:
                                if (IsSocket)
                                {
                                    int sendSize = Socket.Send(sendData.Array, sendData.Start, sendData.Length, SocketFlags.None, out socketError);
                                    sendData.MoveStart(sendSize);
                                    if (sendData.Length == 0)
                                    {
                                        buildInfo.SendSizeLessCount = 0;
                                        if (buildInfo.IsNewBuffer == 0)
                                        {
                                            freeCopyBuffer();
                                            if (head == null)
                                            {
                                                currentOutputSleep = int.MinValue;
                                                goto RESET;
                                            }
                                            if (outputStream.Data.Byte != start)
                                            {
                                                outputStream.Reset(start, Buffer.Length);
                                            }
                                            buildInfo.Clear();
                                            outputStream.ByteSize = 0;
                                            //currentOutputSleep = outputSleep;
                                            goto LOOP;
                                        }
                                        CompressBuffer.TryFree();
                                        if (head != null)
                                        {
                                            Outputs.PushHead(ref head, end);
                                        }
                                        //currentOutputSleep = outputSleep;
                                        goto DISPOSE;
                                    }
                                    if (socketError == SocketError.Success && (sendSize >= TcpServer.Server.MinSocketSize || (sendSize > 0 && buildInfo.SendSizeLessCount++ == 0)))
                                    {
                                        goto SEND;
                                    }
                                    buildInfo.IsError = true;
                                }
                                buildInfo.IsNewBuffer = 0;
                                DISPOSE :;
                            }
                            if (buildInfo.IsNewBuffer == 0)
                            {
                                if (!buildInfo.IsError)
                                {
                                    if (IsSocket)
                                    {
                                        //IsOutput = 0;
                                        Interlocked.Exchange(ref IsOutput, 0);
                                        if (!Outputs.IsEmpty)
                                        {
                                            if (Interlocked.CompareExchange(ref IsOutput, 1, 0) == 0)
                                            {
                                                goto STREAM;
                                            }
                                        }
                                        else if (!IsSocket && Interlocked.CompareExchange(ref IsOutput, 1, 0) == 0)
                                        {
                                            buildInfo.IsClose = true;
                                        }
                                    }
                                    else
                                    {
                                        buildInfo.IsClose = true;
                                    }
                                }
                                return;
                            }
                        }
                    }while (buildInfo.IsNewBuffer != 0);
                }
                catch (Exception error)
                {
                    Server.Log.add(AutoCSer.Log.LogType.Error, error);
                    buildInfo.IsError = true;
                }
                finally
                {
                    if (buildInfo.IsError | buildInfo.IsClose)
                    {
                        if (buildInfo.IsError)
                        {
                            closeSocket();
                        }
                        else
                        {
                            close();
                        }
                        TcpStreamServer.ServerOutput.OutputLink.CancelLink(head);
                    }
                }
            }
            else
            {
                close();
            }
        }