/// <summary> /// TCP调用 /// </summary> /// <typeparam name="inputParameterType">输入参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="inputParameter">输入参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Call <inputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter) where inputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (commandInfo.IsVerifyMethod || getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { outputStream.Reset(dataFixed + Buffer.StartIndex, Buffer.Length); build(commandInfo, ref inputParameter, ref clientBuffer); } if (clientBuffer.Send(this)) { int size = Socket.Receive(Buffer.Buffer, Buffer.StartIndex, sizeof(int), SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if (size == sizeof(uint)) { clientBuffer.SetReturnType((TcpServer.ReturnType)Buffer.Buffer[Buffer.StartIndex]); } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; } } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// TCP调用并返回参数值 /// </summary> /// <typeparam name="outputParameterType">输出参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="outputParameter">输出参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Get <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter) where outputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { *(uint *)(dataFixed + Buffer.StartIndex) = (uint)commandInfo.Command | (uint)TcpServer.CommandFlags.NullData | (uint)commandInfo.CommandFlags; clientBuffer.IsError = true; int size = Socket.Send(Buffer.Buffer, Buffer.StartIndex, sizeof(uint), SocketFlags.None, out clientBuffer.SocketError); ++SendCount; if (size == sizeof(uint)) { receive(commandInfo, ref outputParameter, ref clientBuffer); } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientSendError; } } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// TCP调用并返回参数值 /// </summary> /// <typeparam name="inputParameterType">输入参数类型</typeparam> /// <typeparam name="outputParameterType">输出参数类型</typeparam> /// <param name="commandInfo">命令信息</param> /// <param name="inputParameter">输入参数</param> /// <param name="outputParameter">输出参数</param> /// <returns>返回值类型</returns> public unsafe TcpServer.ReturnType Get <inputParameterType, outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter, ref outputParameterType outputParameter) where inputParameterType : struct where outputParameterType : struct { ClientBuffer clientBuffer = default(ClientBuffer); Monitor.Enter(SocketLock); try { if (IsDisposed == 0) { if (commandInfo.IsVerifyMethod || getSocket()) { fixed(byte *dataFixed = Buffer.GetFixedBuffer()) { outputStream.Reset(dataFixed + Buffer.StartIndex, Buffer.Length); build(commandInfo, ref inputParameter, ref clientBuffer); } if (clientBuffer.Send(this)) { clientBuffer.Free(); receive(commandInfo, ref outputParameter, ref clientBuffer); } } else { clientBuffer.ReturnType = TcpServer.ReturnType.ClientException; } } } finally { isCheck = 0; if (clientBuffer.IsError) { closeSocket(); } Monitor.Exit(SocketLock); clientBuffer.Free(); } return(clientBuffer.ReturnType); }
/// <summary> /// 数据反序列化 /// </summary> /// <typeparam name="outputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="outputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void deSerialize <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter, ref ClientBuffer clientBuffer) where outputParameterType : struct { if ((commandInfo.CommandFlags & TcpServer.CommandFlags.JsonSerialize) == 0) { if (commandInfo.SimpleSerializeOutputParamter == 0) { if (receiveDeSerializer == null) { receiveDeSerializer = AutoCSer.BinaryDeSerializer.YieldPool.Default.Pop() ?? new AutoCSer.BinaryDeSerializer(); receiveDeSerializer.SetTcpServer(AutoCSer.BinaryDeSerializer.DefaultConfig, null); } if (receiveDeSerializer.DeSerializeTcpServer(ref clientBuffer.Data, ref outputParameter)) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } else { fixed(byte *dataFixed = clientBuffer.Data.GetFixedBuffer()) { byte *start = dataFixed + clientBuffer.Data.Start, end = start + clientBuffer.Data.Length; if (SimpleSerialize.TypeDeSerializer <outputParameterType> .DeSerialize(start, ref outputParameter, end) == end) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } } } else { if (receiveJsonParser == null) { receiveJsonParser = AutoCSer.JsonDeSerializer.YieldPool.Default.Pop() ?? new AutoCSer.JsonDeSerializer(); receiveJsonParser.SetTcpServer(); } if (receiveJsonParser.DeSerializeTcpServer(ref clientBuffer.Data, ref outputParameter)) { clientBuffer.ReturnType = TcpServer.ReturnType.Success; return; } } clientBuffer.ReturnType = TcpServer.ReturnType.ClientDeSerializeError; }
/// <summary> /// 接收数据 /// </summary> /// <typeparam name="outputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="outputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void receive <outputParameterType>(TcpServer.CommandInfoBase commandInfo, ref outputParameterType outputParameter, ref ClientBuffer clientBuffer) where outputParameterType : struct { int compressionDataSize, dataSize = 0, nextSize, receiveSize = Socket.Receive(Buffer.Buffer, Buffer.StartIndex, Buffer.Length, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if (receiveSize >= sizeof(int) * 2) { fixed(byte *bufferFixed = Buffer.GetFixedBuffer()) { byte *start = bufferFixed + Buffer.StartIndex; if ((compressionDataSize = *(int *)start) > 0) { if ((nextSize = compressionDataSize + sizeof(int) - receiveSize) == 0) { clientBuffer.IsError = false; if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(ref Buffer, compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); return; } if (nextSize > 0 && clientBuffer.SocketError == SocketError.Success) { if (nextSize <= Buffer.Length) { goto RECEIVE; } else { goto BIGBUFFER; } } } else if (compressionDataSize < 0) { if ((compressionDataSize = -compressionDataSize) <= (dataSize = *(int *)(start + sizeof(int)))) { if ((nextSize = compressionDataSize + sizeof(int) * 2 - receiveSize) == 0) { clientBuffer.IsError = false; if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } return; } if (nextSize > 0) { if (nextSize <= Buffer.Length) { goto RECEIVE; } else { goto BIGBUFFER; } } } } else if (receiveSize == sizeof(int) * 2) { clientBuffer.ReturnType = (TcpServer.ReturnType)(*(start + sizeof(int))); return; } } } clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; BIGBUFFER: clientBuffer.CopyBufferData(ref Buffer, receiveSize + nextSize, receiveSize); if (clientBuffer.CopyBuffer.Length > SendBufferMaxSize) { do { int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if ((nextSize -= count) == 0) { clientBuffer.IsError = false; if (dataSize == 0) { if (ReceiveMarkData != 0) { Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } else { if (ReceiveMarkData != 0) { Mark(clientBuffer.CopyBuffer.Buffer, ReceiveMarkData, clientBuffer.CopyBuffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } } return; } if (count <= 0 || clientBuffer.SocketError != SocketError.Success) { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; } receiveSize += count; }while (true); } Buffer.Free(); clientBuffer.CopyBuffer.CopyToClear(ref Buffer); RECEIVE: do { int count = Socket.Receive(Buffer.Buffer, Buffer.StartIndex + receiveSize, nextSize, SocketFlags.None, out clientBuffer.SocketError); ++ReceiveCount; if ((nextSize -= count) == 0) { clientBuffer.IsError = false; if (dataSize == 0) { if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int), compressionDataSize); } clientBuffer.SetReceiveData(ref Buffer, compressionDataSize); deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } else { if (ReceiveMarkData != 0) { Mark(Buffer.Buffer, ReceiveMarkData, Buffer.StartIndex + sizeof(int) * 2, compressionDataSize); } if (clientBuffer.DeCompressReceiveData(ref Buffer, compressionDataSize, dataSize)) { deSerialize(commandInfo, ref outputParameter, ref clientBuffer); } } return; } if (count <= 0 || clientBuffer.SocketError != SocketError.Success) { clientBuffer.ReturnType = TcpServer.ReturnType.ClientReceiveError; return; } receiveSize += count; }while (true); }
/// <summary> /// 创建命令输入数据 /// </summary> /// <typeparam name="inputParameterType"></typeparam> /// <param name="commandInfo"></param> /// <param name="inputParameter"></param> /// <param name="clientBuffer"></param> private unsafe void build <inputParameterType>(TcpServer.CommandInfoBase commandInfo, ref inputParameterType inputParameter, ref ClientBuffer clientBuffer) where inputParameterType : struct { byte *start = outputStream.Data.Byte; outputStream.Data.CurrentIndex = sizeof(uint) + sizeof(int); if ((commandInfo.CommandFlags & TcpServer.CommandFlags.JsonSerialize) == 0) { if (commandInfo.SimpleSerializeInputParamter == 0) { int parameterIndex = commandInfo.InputParameterIndex; if (serializeParameterIndex == parameterIndex) { outputSerializer.SerializeTcpServerNext(ref inputParameter); } else { outputSerializer.SerializeTcpServer(ref inputParameter); serializeParameterIndex = parameterIndex; } } else { SimpleSerialize.TypeSerializer <inputParameterType> .Serializer(outputStream, ref inputParameter); } } else { if (outputJsonSerializer == null) { outputJsonSerializer = AutoCSer.JsonSerializer.YieldPool.Default.Pop() ?? new AutoCSer.JsonSerializer(); outputJsonSerializer.SetTcpServer(); } outputJsonSerializer.SerializeTcpServer(ref inputParameter, outputSerializer.Stream); } int dataLength = outputStream.Data.CurrentIndex - (sizeof(uint) + sizeof(int)); if (dataLength <= maxInputSize) { byte *write = outputStream.Data.Byte; *(uint *)write = (uint)commandInfo.Command | (uint)commandInfo.CommandFlags; *(int *)(write + sizeof(uint)) = dataLength; if (outputStream.Data.CurrentIndex <= Buffer.Length) { if (start != write) { AutoCSer.Memory.Common.CopyNotNull(write, start, outputStream.Data.CurrentIndex); } clientBuffer.Data.Set(Buffer.Buffer, Buffer.StartIndex, outputStream.Data.CurrentIndex); } else { outputStream.Data.GetSubBuffer(ref clientBuffer.CopyBuffer); clientBuffer.SetSendDataCopyBuffer(outputStream.Data.CurrentIndex); if (clientBuffer.CopyBuffer.Length <= SendBufferMaxSize) { Buffer.Free(); clientBuffer.CopyBuffer.CopyToClear(ref Buffer); } } if (dataLength < MinCompressSize || !clientBuffer.CompressSendData(dataLength, SendMarkData)) { if (SendMarkData == 0) { clientBuffer.IsError = true; } else { clientBuffer.MarkSendData(dataLength, SendMarkData); } } } }