예제 #1
0
        private Packet GetPingPacket(FalconPeer peerToBorrowPacketFrom)
        {
            var pingPacket = peerToBorrowPacketFrom.BorrowPacketFromPool();

            pingPacket.WriteByte((byte)FalconTestMessageType.Ping);
            return(pingPacket);
        }
 internal DatagramSocketTransceiver(FalconPeer localPeer)
 {
     this.localPeer      = localPeer;
     this.messagesBuffer = new byte[localPeer.ReceiveBufferSize];
     this.messageDetails = new Queue <MessageDetail>();
     this.outputStreams  = new Dictionary <IPEndPoint, IOutputStream>();
 }
예제 #3
0
        private IEnumerable <FalconPeer> ConnectXNumOfPeers(FalconPeer host, int numOfOtherPeers, string pass)
        {
            var otherPeers = new List <FalconPeer>(numOfOtherPeers);

            for (var i = 0; i < numOfOtherPeers; i++)
            {
                var otherPeer = CreateAndStartLocalPeer();

                // connect to the host
                ConnectToLocalPeer(otherPeer, host, pass);

                // connect to each other peer
                foreach (var peer in otherPeers)
                {
                    ConnectToLocalPeer(otherPeer, peer, pass);
                }

                // allow future other peers to connect to this one
                otherPeer.SetVisibility(true, pass, false);

                otherPeers.Add(otherPeer);
            }

            foreach (var fp in otherPeers)
            {
                fp.SetVisibility(false, null, false);
            }

            return(otherPeers);
        }
예제 #4
0
        private FalconPeer CreateAndStartLocalPeer(int port = -1, float ackTimeout = Single.NaN, float keepAliveInterval = Single.NaN)
        {
            if (port == -1)
            {
                port = GetUnusedPortNumber();
            }
#if DEBUG
            FalconPeer peer = new FalconPeer(port, ProcessReceivedPacket, FalconPoolSizes.Default, null, LogLevel.Debug);
#else
            FalconPeer peer = new FalconPeer(port, ProcessReceivedPacket, FalconPoolSizes.Default);
#endif
            if (!Single.IsNaN(ackTimeout))
            {
                peer.AckTimeout = TimeSpan.FromSeconds(ackTimeout);
            }

            if (!Single.IsNaN(keepAliveInterval))
            {
                peer.KeepAliveInterval = TimeSpan.FromSeconds(keepAliveInterval);
            }

            var tr = peer.TryStart();
            Assert.IsTrue(tr.Success, tr.NonSuccessMessage);
            if (tr.Success)
            {
                lock (activePeers)
                {
                    activePeers.Add(peer);
                }
            }
            return(peer);
        }
예제 #5
0
 public AutonomousTransciever(FalconPeer localPeer)
 {
     this.localPeer               = localPeer;
     this.anyAddrEndPoint         = new IPEndPoint(IPAddress.Any, localPeer.Port);
     this.socket                  = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
     this.lastDatagramBuffer      = new byte[FalconPeer.MaxDatagramSize];
     this.receivedDatagramsBuffer = new byte[localPeer.ReceiveBufferSize];
     this.receivedDatagramDetails = new Queue <DatagramDetail>();
 }
예제 #6
0
        internal static IFalconTransceiver Create(FalconPeer localPeer)
        {
#if NETFX_CORE && !WINDOWS_UWP
            return(new DatagramSocketTransceiver(localPeer));
#elif PS4
            return(new AutonomousTransciever(localPeer));
#else
            return(new SocketTransceiver(localPeer));
#endif
        }
예제 #7
0
 internal ReceiveChannel(SendOptions channelType, FalconPeer localPeer, RemotePeer remotePeer)
 {
     this.channelType     = channelType;
     this.localPeer       = localPeer;
     this.remotePeer      = remotePeer;
     this.isReliable      = (channelType & SendOptions.Reliable) == SendOptions.Reliable;
     this.isInOrder       = (channelType & SendOptions.InOrder) == SendOptions.InOrder;
     this.receivedPackets = new SortedList <float, Packet>();
     this.packetsRead     = new List <Packet>();
     this.numberOfDatagramSequencesReadToKeep = localPeer.MaxOutOfOrderTolerence * 2;
     this.datagramsSeqRecentlyRead            = new List <ushort>(this.numberOfDatagramSequencesReadToKeep);
 }
예제 #8
0
        private void ConnectToLocalPeer(FalconPeer peer, FalconPeer remotePeer, string pass, Packet userData = null)
        {
            var mre = new ManualResetEvent(false);
            FalconOperationResult <int> result = null;

            lock (falconPeerLock)
            {
                peer.TryJoinPeerAsync("127.0.0.1", remotePeer.Port, pass, rv =>
                {
                    result = rv;
                    mre.Set();
                }, userData);
            }
            mre.WaitOne();
            Assert.IsTrue(result.Success, result.NonSuccessMessage);
        }
예제 #9
0
        internal void Init(FalconPeer falconPeer,
                           bool listenForReply,
                           float durationSeconds,
                           int numOfSignalsToEmit,
                           int maxNumOfPeersToDiscover,
                           IEnumerable <IPEndPoint> endPointsToSendTo,
                           Guid?token,
                           DiscoveryCallback callback)
        {
            // NOTE: This class is re-used from a pool so this method needs to fully reset
            //       the class.

            if (listenForReply)
            {
                Debug.Assert(callback != null, "callback required if listening for a reply");
            }
            else
            {
                Debug.Assert(callback == null, "callback must be null if not listening for a reply");
            }
            Debug.Assert(maxNumOfPeersToDiscover > 0, "max no. of peers to receive a reply must be greater than 0");

            this.TaskEnded                = false;
            this.falconPeer               = falconPeer;
            this.emitCount                = 0;
            this.listenForReply           = listenForReply;
            this.callback                 = callback;
            this.secondsBetweenEmits      = (durationSeconds / numOfSignalsToEmit);
            this.totalEmits               = numOfSignalsToEmit;
            this.maxNumberPeersToDiscover = maxNumOfPeersToDiscover;
            this.token = token;
            this.ellapsedSecondsSinceLastEmit = 0.0f;

            if (token.HasValue)
            {
                Buffer.BlockCopy(Const.DISCOVER_PACKET_WITH_TOKEN_HEADER, 0, signal, 0, Const.DISCOVER_PACKET_WITH_TOKEN_HEADER.Length);
                Buffer.BlockCopy(token.Value.ToByteArray(), 0, signal, Const.DISCOVER_PACKET.Length, Const.DISCOVERY_TOKEN_SIZE);
            }
            else
            {
                Buffer.BlockCopy(Const.DISCOVER_PACKET, 0, signal, 0, Const.DISCOVER_PACKET.Length);
            }

            this.endPointsToSendTo.Clear();
            this.endPointsToSendTo.AddRange(endPointsToSendTo);
            this.endPointsReceivedReplyFrom.Clear();
        }
예제 #10
0
        internal RemotePeer(FalconPeer localPeer, IPEndPoint endPoint, int peerId, bool keepAliveAndAutoFlush = true)
        {
            this.Id        = peerId;
            this.localPeer = localPeer;
            this.endPoint  = endPoint;
#if DEBUG
            this.PeerName = endPoint.ToString();
#else
            this.PeerName = String.Empty;
#endif
            this.unreadPacketCount        = 0;
            this.sendDatagramsPool        = new DatagramPool(FalconPeer.MaxDatagramSize, localPeer.PoolSizes.InitalNumSendDatagramsToPoolPerPeer);
            this.sentDatagramsAwaitingACK = new List <Datagram>();
            this.qualityOfService         = new QualityOfService(localPeer.LatencySampleSize, localPeer.ResendRatioSampleSize);

            this.delayedDatagrams      = new List <DelayedDatagram>();
            this.keepAliveAndAutoFlush = keepAliveAndAutoFlush;
            this.allUnreadPackets      = new List <Packet>();
            this.enqueudAcks           = new Queue <AckDetail>();

            CreateSendRecieveChannels();
        }
예제 #11
0
        private void Tick()
        {
            lock (falconPeerLock)
            {
                lock (activePeers)
                {
                    foreach (var peer in activePeers)
                    {
                        peerProcessingReceivedPacketsFor = peer;
                        if (peer.IsStarted)
                        {
                            peer.Update();

                            if (!disableSendFromPeers.Contains(peer))
                            {
                                peer.SendEnquedPackets();
                            }
                        }
                    }
                }
            }
        }
예제 #12
0
 public SocketTransceiver(FalconPeer localPeer)
 {
     this.localPeer       = localPeer;
     this.anyAddrEndPoint = new IPEndPoint(IPAddress.Any, localPeer.Port);
     this.socket          = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 }
예제 #13
0
        private void ProcessReceivedPacket(Packet packet)
        {
            IPEndPoint sender;
            FalconPeer peer = peerProcessingReceivedPacketsFor;

            if (!peer.TryGetPeerIPEndPoint(packet.PeerId, out sender))
            {
                Debug.WriteLine("Failed to find IPEndPoint of peer packet received from!");
                //Assert.Fail("Failed to find IPEndPoint of peer packet received from!");
                return;
            }

            if (packet.BytesWritten == 0)
            {
                Debug.WriteLine("Empty packet!?");
                return;
            }

            var type = (FalconTestMessageType)packet.ReadByte();

            switch (type)
            {
            case FalconTestMessageType.Ping:
            {
                Debug.WriteLine("Ping received from: {0}, sending pong...", sender);
                var pongPacket = peer.BorrowPacketFromPool();
                pongPacket.WriteByte((byte)FalconTestMessageType.Pong);
                peer.EnqueueSendTo(packet.PeerId, SendOptions.ReliableInOrder, pongPacket);
            }
            break;

            case FalconTestMessageType.Pong:
            {
                Debug.WriteLine("Pong received from: {0}!", sender);
                if (replyReceived != null)
                {
                    replyReceived(sender, packet);
                }
            }
            break;

            case FalconTestMessageType.RandomBytes:
            {
                var opts = (SendOptions)packet.ReadByte();
                //Assert.IsTrue(Enum.IsDefined(typeof(SendOptions), opts), "Invalid SendOptions");
                if (!Enum.IsDefined(typeof(SendOptions), opts))
                {
                    Debug.WriteLine("Invalid SendOptions");
                }
                var length = packet.ReadUInt16();
                Debug.WriteLine(" -> RandomBytes received from: {0}, on channel: {1}, purported length: {2}, actual: {3}", sender, opts, length, packet.BytesRemaining);
                var bytes = packet.ReadBytes(length);

                var reply = peer.BorrowPacketFromPool();
                reply.WriteByte((byte)FalconTestMessageType.RandomBytesReply);
                reply.WriteUInt16((ushort)bytes.Length);
                reply.WriteBytes(bytes);

                peer.EnqueueSendTo(packet.PeerId, opts, reply);
            }
            break;

            case FalconTestMessageType.RandomBytesReply:
            {
                Debug.WriteLine(" <- RandomBytesReply received from: {0}", sender);
                if (replyReceived != null)
                {
                    replyReceived(sender, packet);
                }
            }
            break;

            default:
            {
                //Assert.Fail("Unhandeled FalconTestMessagePacketType: " + type.ToString());
                Debug.WriteLine("Unhandeled FalconTestMessagePacketType: " + type.ToString());
            }
            break;
            }
        }