示例#1
0
        public ReadOnlySpan <byte> Read(int length)
        {
            NetworkReadResult networkReadResult = this.FillBuffer();

            if (networkReadResult.HasError)
            {
                throw new RpcException(
                          $"Could not receive from TCP stream. Socket error: {networkReadResult.SocketError}.");
            }

            if (networkReadResult.IsDisconnected)
            {
                throw new RpcException("Could not receive from TCP stream. Remote end point disconnected.");
            }

            int endIndex = Math.Min(this.headerIndex, this.buffer.Length);

            endIndex = Math.Min(endIndex, this.writeIndex);
            int availableBytes = endIndex - this.readIndex;
            int bytesToRead    = Math.Min(availableBytes, length);

            Span <byte> span = this.buffer.AsSpan(this.readIndex, bytesToRead);

            this.readIndex += bytesToRead;
            return(span);
        }
示例#2
0
        private void HandlingUdpCalls()
        {
            while (!this.stopReceiving)
            {
                try
                {
                    NetworkReadResult result = this.reader.BeginReading();
                    if (result.HasError)
                    {
                        this.logger?.Trace($"Could not read UDP data. Socket error: {result.SocketError}.");
                        continue;
                    }

                    if (result.IsDisconnected)
                    {
                        // Should only happen on dispose
                        continue;
                    }

                    this.writer.BeginWriting();
                    this.receivedCall.HandleCall(new Caller(result.RemoteIpEndPoint, Protocol.Udp));
                    this.reader.EndReading();
                    this.writer.EndWriting(result.RemoteIpEndPoint);
                }
                catch (Exception e)
                {
                    this.logger?.Error($"The following error occurred while processing UDP call: {e}");
                }
            }
        }
示例#3
0
        private bool SendMessage(int procedure, int version, IXdrWritable argument, out string errorMessage)
        {
            this.networkWriter.BeginWriting();

            this.rpcMessage.Xid = this.nextXid++;
            this.rpcMessage.Body.CallBody.Procedure = (uint)procedure;
            this.rpcMessage.Body.CallBody.Version   = (uint)version;
            this.rpcMessage.WriteTo(this.xdrWriter);
            argument.WriteTo(this.xdrWriter);

            NetworkWriteResult writeResult = this.networkWriter.EndWriting(this.remoteIpEndPoint);

            if (writeResult.HasError)
            {
                errorMessage =
                    $"Could not send message to {this.remoteIpEndPoint}. Socket error: {writeResult.SocketError}.";
                return(false);
            }

            NetworkReadResult readResult = this.networkReader.BeginReading();

            if (readResult.HasError)
            {
                errorMessage =
                    $"Could not receive reply from {this.remoteIpEndPoint}. Socket error: {readResult.SocketError}.";
                return(false);
            }

            errorMessage = null;
            return(true);
        }
示例#4
0
        public NetworkReadResult BeginReading()
        {
            this.readIndex = 0;
            try
            {
                this.totalLength = this.udpClient.ReceiveFrom(this.buffer, SocketFlags.None, ref this.remoteEndPoint);
                if (this.totalLength == 0)
                {
                    return(NetworkReadResult.CreateDisconnected());
                }

                return(NetworkReadResult.CreateSuccess((IPEndPoint)this.remoteEndPoint));
            }
            catch (SocketException e)
            {
                return(NetworkReadResult.CreateError(e.SocketErrorCode));
            }
        }
示例#5
0
        private void Receiving()
        {
            try
            {
                while (!this.stopReceiving)
                {
                    NetworkReadResult readResult = this.reader.BeginReading();
                    if (readResult.HasError)
                    {
                        this.logger?.Trace(
                            $"Could not read data from {this.caller}. " +
                            $"Socket error: {readResult.SocketError}.");
                        this.IsFinished = true;
                        return;
                    }

                    if (readResult.IsDisconnected)
                    {
                        this.logger?.Trace($"{this.caller} disconnected.");
                        this.IsFinished = true;
                        return;
                    }

                    this.writer.BeginWriting();
                    this.receivedCall.HandleCall(this.caller);
                    this.reader.EndReading();

                    NetworkWriteResult writeResult = this.writer.EndWriting(this.remoteIpEndPoint);
                    if (writeResult.HasError)
                    {
                        this.logger?.Trace(
                            $"Could not write data to {this.caller}. " +
                            $"Socket error: {writeResult.SocketError}.");
                        this.IsFinished = true;
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                this.logger?.Error($"Unexpected exception in connection to {this.caller}: {e}");
            }
        }
示例#6
0
        private NetworkReadResult ReadFromNetwork(ref bool readFromNetwork)
        {
            int         receivedLength;
            SocketError socketError;

            try
            {
                receivedLength = this.tcpClient.Receive(
                    this.buffer,
                    this.writeIndex,
                    this.buffer.Length - this.writeIndex,
                    SocketFlags.None,
                    out socketError);
            }
            catch (SocketException exception)
            {
                return(NetworkReadResult.CreateError(exception.SocketErrorCode));
            }
            catch (Exception exception)
            {
                this.logger?.Error(
                    $"Unexpected error while receiving TCP data from {this.tcpClient?.RemoteEndPoint}: {exception}");
                return(NetworkReadResult.CreateError(SocketError.SocketError));
            }

            if (socketError != SocketError.Success)
            {
                return(NetworkReadResult.CreateError(socketError));
            }

            if (receivedLength == 0)
            {
                return(NetworkReadResult.CreateDisconnected());
            }

            this.writeIndex += receivedLength;
            readFromNetwork  = false;
            return(NetworkReadResult.CreateSuccess());
        }
示例#7
0
        // On the first iteration, this function will read as many data from the network as available
        // On the following iterations, it depends on the yet received data:
        // - Not enough bytes for header? Read from network again
        // - Packet is not complete and there is space left in the buffer? Read from network again
        // - Packet is not complete and no space available? Return and wait for XDR read
        // - Packet is complete and XDR read is not complete? Return and wait for XDF read
        // - Packet and XDR read is complete? Read next header. Or finish if previous packet was the last packet
        private NetworkReadResult FillBuffer()
        {
            bool readFromNetwork = false;

            while (true)
            {
                if (this.packetState == PacketState.Complete)
                {
                    return(NetworkReadResult.CreateSuccess());
                }

                if (this.packetState == PacketState.Header)
                {
                    this.ReadHeader(ref readFromNetwork);
                }

                if (this.packetState == PacketState.Body)
                {
                    if (this.ReadBody(ref readFromNetwork))
                    {
                        return(NetworkReadResult.CreateSuccess());
                    }
                }

                if (readFromNetwork)
                {
                    NetworkReadResult networkReadResult = this.ReadFromNetwork(ref readFromNetwork);
                    if (networkReadResult.HasError || networkReadResult.IsDisconnected)
                    {
                        return(networkReadResult);
                    }
                }

                this.ShiftData();
            }
        }