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); }
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}"); } } }
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); }
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)); } }
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}"); } }
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()); }
// 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(); } }