예제 #1
0
        //When finished broadcast send
        private static void EndBroadcastSend(IAsyncResult asyncResult)
        {
            //Extract UnreliableTransmissionState from Async State
            BroadcastTransmissionState transmissionState = (BroadcastTransmissionState)asyncResult.AsyncState;
            Socket broadcaster = transmissionState.broadcaster;

            try
            {
                broadcaster.EndSend(asyncResult);

                //Callback of transmission state
                if (transmissionState.callback != null)
                {
                    transmissionState.callback();
                }
            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(ObjectDisposedException) || broadcaster == null || !broadcaster.IsBound)
                {
                    return;
                }

                Debug.LogError("Error sending unreliable packet to server: " + ex);
            }
        }
예제 #2
0
        /// <summary>
        /// Setup the broadcast channel for the given adapter address and port.
        /// </summary>
        /// <param name="adapterAddress">The Network Adapter address to be used for broadcasting.
        /// See <see cref="NUUtilities.ListIPv4Addresses()"/> for valid sources.</param>
        /// <param name="broadcastPort">The port in which the broadcast will happen.</param>
        public static void SetupBroadcast(IPAddress adapterAddress    = null, ushort broadcastServerPort = 56552, Action updateHook = null,
                                          int reservedBufferedPackets = NUUtilities.MaxBufferedPackets)
        {
            //Loopback address if none are given
            if (adapterAddress == null)
            {
                adapterAddress = IPAddress.Loopback;
            }
            NUClient.broadcastServerPort = broadcastServerPort;

            // Setup broadcast ranges and receiving queue
            IPAddress subnet     = NUUtilities.GetSubnetMaskFromIPv4(adapterAddress);
            UInt32    subnetInt  = NUUtilities.GetUIntFromIpAddress(subnet);
            UInt32    addressInt = NUUtilities.GetUIntFromIpAddress(adapterAddress);

            broadcastStartRange = (addressInt & subnetInt) + 1;
            broadcastFinalRange = (addressInt | (~subnetInt)) - 1;
            lock (broadcastDataQueueLock)
            {
                broadcastDataQueue = new Queue <BroadcastPacket>(reservedBufferedPackets);
            }
            IPEndPoint broadcastEp = new IPEndPoint(adapterAddress, 0);

            broadcaster = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
            {
                ExclusiveAddressUse = true
            };
            broadcaster.Bind(broadcastEp);
            BroadcastTransmissionState broadcastState = new BroadcastTransmissionState(
                NUUtilities.MTU, ref broadcaster, null);
            EndPoint broadcastSenderEp = broadcastState.senderEp;

            broadcaster.BeginReceiveFrom(broadcastState.data, 0, NUUtilities.MTU, SocketFlags.None,
                                         ref broadcastSenderEp, new AsyncCallback(EndBroadcastReceive), broadcastState);

            //Hook on updateHook otherwise instantiate NUClientComponent
            if (updateHook != null)
            {
                updateHook += ProcessQueues;
            }
            else
            {
                //Create MonoBehaviour instance if it doesn't exists
                if (clientComponent == null)
                {
                    GameObject clientObject = new GameObject("NUClientObject");
                    //clientObject.hideFlags = HideFlags.HideAndDontSave;
                    GameObject.DontDestroyOnLoad(clientObject);
                    clientComponent = clientObject.AddComponent <NUClientComponent>();
                    //clientObject.hideFlags = HideFlags.HideInInspector;
                }
            }
        }
예제 #3
0
        private static void EndBroadcastReceive(IAsyncResult asyncResult)
        {
            //Extract UDPClient from Async State
            BroadcastTransmissionState broadcastState = (BroadcastTransmissionState)asyncResult.AsyncState;
            Socket broadcaster = broadcastState.broadcaster;

            try
            {
                //End receiving data
                int receivedSize = broadcaster.EndReceiveFrom(asyncResult, ref broadcastState.senderEp);

                if (receivedSize > 0)
                {
                    //Get Message flag and process accordingly
                    Packet receivedPacket = new Packet(broadcastState.data, receivedSize);

                    //Ignore packets that are not valid in our broadcast routines
                    if (receivedPacket.flag == Packet.TypeFlag.BROADCAST)
                    {
                        BroadcastPacket broadcastPacket = new BroadcastPacket(receivedPacket,
                                                                              (IPEndPoint)broadcastState.senderEp);
                        lock (broadcastDataQueueLock)
                        {
                            broadcastDataQueue.Enqueue(broadcastPacket);
                        }
                    }
                }

                //Keep receiving data
                broadcaster.BeginReceiveFrom(broadcastState.data, 0, NUUtilities.MTU, SocketFlags.None,
                                             ref broadcastState.senderEp, new AsyncCallback(EndBroadcastReceive), broadcastState);
            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(ObjectDisposedException) || broadcaster == null || !broadcaster.IsBound)
                {
                    return;
                }

                Debug.LogError("Error occurred receiving broadcast packet: " + ex.Message);

                //Keep receiving data (because one connection error should not eliminate other responses)
                broadcaster.BeginReceiveFrom(broadcastState.data, 0, NUUtilities.MTU, SocketFlags.None,
                                             ref broadcastState.senderEp, new AsyncCallback(EndBroadcastReceive), broadcastState);
            }
        }
예제 #4
0
        /// <summary>
        /// Broadcast a Packet (whose destination doesn't matter)
        /// </summary>
        /// <param name="emptyDestinationPacket">An packet whose destination doesn't matter</param>
        public static void Broadcast(Packet emptyDestinationPacket, Action callback = null)
        {
            if (broadcaster == null)
            {
                Debug.LogWarning("Broadcast not configured! Using default settings...\n" +
                                 "Call NUClient.SetupBroadcast() with corrent parameters.");
                SetupBroadcast();
            }

            if (emptyDestinationPacket.data == null)
            {
                Debug.LogError("Data to be sent is null!");
                return;
            }

            if (emptyDestinationPacket.data.Length == 0)
            {
                Debug.LogError("Data to be sent is empty!");
                return;
            }

            // Set Broadcast Flag if not already
            if (emptyDestinationPacket.flag != Packet.TypeFlag.BROADCAST)
            {
                emptyDestinationPacket.OverridePacketFlag(Packet.TypeFlag.BROADCAST);
            }

            BroadcastTransmissionState transmissionState = new BroadcastTransmissionState(
                emptyDestinationPacket.data.Length, ref broadcaster, callback);

            // Send a broadcast transmission to the full range of IPs range
            IPEndPoint receivingEp = (IPEndPoint)broadcaster.LocalEndPoint;

            for (uint ip = broadcastStartRange + 1; ip < broadcastFinalRange; ip++)
            {
                IPAddress  broadcastIp = NUUtilities.GetIpAddressFromUInt32(ip);
                IPEndPoint broadcastEp = new IPEndPoint(broadcastIp, broadcastServerPort);

                broadcaster.BeginSendTo(emptyDestinationPacket.data, 0, emptyDestinationPacket.data.Length,
                                        SocketFlags.None, broadcastEp, new AsyncCallback(EndBroadcastSend), transmissionState);
            }
        }