/// <summary> /// Receive TcpClient from remote computer. /// </summary> /// <returns>Accepted TcpClient</returns> /// <exception cref="Exception">Thrown if TcpListener not started.</exception> public TcpClient AcceptTcpClient(int timeout = -1) { if (StateMachine == null) { new Exception("TcpListener is not started."); } if (StateMachine.Status == Status.CLOSED) // if TcpListener already accepted client, remove old one. { Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); Start(); } if (timeout == -1) { while (StateMachine.WaitStatus(Status.ESTABLISHED) != true) { ; } } else { while (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) != true) { ; } } return(new TcpClient(StateMachine)); }
/// <summary> /// Connect to client. /// </summary> /// <param name="dest">Destination address.</param> /// <param name="destPort">Destination port.</param> /// <exception cref="Exception">Thrown if TCP Status is not CLOSED.</exception> public void Connect(Address dest, int destPort, int timeout = 5000) { if (StateMachine.Status != Status.CLOSED) { throw new Exception("Client must be closed before setting a new connection."); } StateMachine.destination = dest; StateMachine.destinationPort = destPort; StateMachine.source = IPConfig.FindNetwork(dest); //Generate Random Sequence Number var rnd = new Random(); StateMachine.SequenceNumber = (uint)((rnd.Next(0, Int32.MaxValue)) << 32) | (uint)(rnd.Next(0, Int32.MaxValue)); // Flags=0x02 -> Syn var packet = new TCPPacket(StateMachine.source, StateMachine.destination, (ushort)StateMachine.localPort, (ushort)destPort, StateMachine.SequenceNumber, 0, 20, (byte)Flags.SYN, 0xFAF0, 0); OutgoingBuffer.AddPacket(packet); NetworkStack.Update(); StateMachine.Status = Status.SYN_SENT; if (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) == false) { throw new Exception("Failed to open TCP connection!"); } }
/// <summary> /// Receive TcpClient from remote computer. /// </summary> /// <returns>Accepted TcpClient</returns> public TcpClient AcceptTcpClient(int timeout = -1) { if (timeout == -1) { while (StateMachine.WaitStatus(Status.ESTABLISHED) != true) { ; } } else { while (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) != true) { ; } } return(new TcpClient(StateMachine)); }
/// <summary> /// Connect to client. /// </summary> /// <param name="dest">Destination address.</param> /// <param name="destPort">Destination port.</param> /// <exception cref="Exception">Thrown if TCP Status is not CLOSED.</exception> public void Connect(Address dest, int destPort, int timeout = 5000) { if (StateMachine.Status == Status.ESTABLISHED) { throw new Exception("Client must be closed before setting a new connection."); } StateMachine.RemoteEndPoint.Address = dest; StateMachine.LocalEndPoint.Address = IPConfig.FindNetwork(dest); StateMachine.RemoteEndPoint.Port = (ushort)destPort; //Generate Random Sequence Number var rnd = new Random(); var SequenceNumber = (uint)((rnd.Next(0, Int32.MaxValue)) << 32) | (uint)(rnd.Next(0, Int32.MaxValue)); //Fill TCB StateMachine.TCB.SndUna = SequenceNumber; StateMachine.TCB.SndNxt = SequenceNumber; StateMachine.TCB.SndWnd = Tcp.TcpWindowSize; StateMachine.TCB.SndUp = 0; StateMachine.TCB.SndWl1 = 0; StateMachine.TCB.SndWl2 = 0; StateMachine.TCB.ISS = SequenceNumber; StateMachine.TCB.RcvNxt = 0; StateMachine.TCB.RcvWnd = Tcp.TcpWindowSize; StateMachine.TCB.RcvUp = 0; StateMachine.TCB.IRS = 0; Tcp.Connections.Add(StateMachine); StateMachine.SendEmptyPacket(Flags.SYN); StateMachine.Status = Status.SYN_SENT; if (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) == false) { throw new Exception("Failed to open TCP connection!"); } }