/// <summary> /// Send data to client. /// </summary> /// <param name="data">Data array to send.</param> /// <exception cref="Exception">Thrown if destination is null or destinationPort is 0.</exception> /// <exception cref="ArgumentException">Thrown on fatal error (contact support).</exception> /// <exception cref="OverflowException">Thrown if data array length is greater than Int32.MaxValue.</exception> /// <exception cref="Sys.IO.IOException">Thrown on IO error.</exception> /// <exception cref="Exception">Thrown if TCP Status is not ESTABLISHED.</exception> public void Send(byte[] data) { if ((StateMachine.RemoteEndPoint.Address == null) || (StateMachine.RemoteEndPoint.Port == 0)) { throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); } if (StateMachine.Status != Status.ESTABLISHED) { throw new Exception("Client must be connected before sending data."); } if (data.Length > 536) { var chunks = ArrayHelper.ArraySplit(data, 536); for (int i = 0; i < chunks.Length; i++) { var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, i == chunks.Length - 2 ? (byte)(Flags.PSH | Flags.ACK) : (byte)(Flags.ACK), StateMachine.TCB.SndWnd, 0, chunks[i]); OutgoingBuffer.AddPacket(packet); NetworkStack.Update(); StateMachine.TCB.SndNxt += (uint)chunks[i].Length; } } else { var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, (byte)(Flags.PSH | Flags.ACK), StateMachine.TCB.SndWnd, 0, data); OutgoingBuffer.AddPacket(packet); NetworkStack.Update(); StateMachine.TCB.SndNxt += (uint)data.Length; } }
/// <summary> /// Send data to client. /// </summary> /// <param name="data">Data array to send.</param> /// <exception cref="Exception">Thrown if destination is null or destinationPort is 0.</exception> /// <exception cref="ArgumentException">Thrown on fatal error (contact support).</exception> /// <exception cref="OverflowException">Thrown if data array length is greater than Int32.MaxValue.</exception> /// <exception cref="Sys.IO.IOException">Thrown on IO error.</exception> /// <exception cref="Exception">Thrown if TCP Status is not ESTABLISHED.</exception> public void Send(byte[] data) { if ((StateMachine.destination == null) || (StateMachine.destinationPort == 0)) { throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); } if (StateMachine.Status != Status.ESTABLISHED) { throw new Exception("Client must be connected before sending data."); } if (data.Length > 536) { var chunks = ArrayHelper.ArraySplit(data, 536); for (int i = 0; i < chunks.Length; i++) { var packet = new TCPPacket(StateMachine.source, StateMachine.destination, (ushort)StateMachine.localPort, (ushort)StateMachine.destinationPort, StateMachine.SequenceNumber, StateMachine.AckNumber, 20, i == chunks.Length - 2 ? (byte)(Flags.PSH | Flags.ACK) : (byte)(Flags.ACK), 0xFAF0, 0, chunks[i]); OutgoingBuffer.AddPacket(packet); NetworkStack.Update(); StateMachine.SequenceNumber += (uint)chunks[i].Length; } } else { var packet = new TCPPacket(StateMachine.source, StateMachine.destination, (ushort)StateMachine.localPort, (ushort)StateMachine.destinationPort, StateMachine.SequenceNumber, StateMachine.AckNumber, 20, (byte)(Flags.PSH | Flags.ACK), 0xFAF0, 0, data); OutgoingBuffer.AddPacket(packet); NetworkStack.Update(); StateMachine.SequenceNumber += (uint)data.Length; } StateMachine.WaitingAck = true; }