예제 #1
0
        /// <summary>
        /// Bind the socket to the local endpoint.
        /// </summary>
        /// <param name="localEndpoint"></param>
        public override void BindSocket(EndPoint localEndpoint)
        {
            // Create a new IPv4 UDP Socket.
            Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
            {
                Blocking = true
            };

            // Bind the local endpoint to the socket.
            Socket.Bind(localEndpoint);
            LocalEndpoint = Socket.LocalEndPoint;

            SkaiaLogger.LogMessage(MessageType.Info, $"Bound socket to {localEndpoint.ToString()}");
            // Set the connection reset.

            RawDataReceived = new Action <byte[], SEndPoint>(DispatchRawPacket);
            NetUtils.SetConnReset(Socket);
        }
예제 #2
0
        /// <summary>
        /// Receive data on the socket. This will block the calling method until it finds something to receive.
        /// </summary>
        /// <param name="buffer"> The buffer to copy the data onto. </param>
        /// <param name="length"> The amount of data to copy. </param>
        /// <param name="sender"> The data's sender. </param>
        /// <returns> The data received or null if nothing. </returns>
        public override byte[] Receive(byte[] buffer, int length, out EndPoint sender)
        {
            if (!Socket.IsBound)
            {
                throw new InvalidOperationException();
            }

            sender = null;

            try
            {
                // Wait indefinitely to receive something on the socket.
                if (Socket.Poll(-1, SelectMode.SelectRead))
                {
                    // Get the length of the packet received.
                    int pcktLength = Socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref recvEndpoint);

                    // If for some odd reason it's empty, we'll just discard it and return an empty byte array.
                    if (pcktLength > 0)
                    {
                        byte[] data = new byte[pcktLength];
                        Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
                        sender = recvEndpoint;
                        return(data);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            catch (Exception ex)
            {
                // This probably happens if the socket isn't bound.
                SkaiaLogger.LogMessage(MessageType.Error, "Failed to poll and receive on socket.", ex);
                sender = null;
            }

            return(null);
        }
예제 #3
0
        /// <summary>
        /// Tries to find a network interface with a valid IPv4 address and returns it.
        /// </summary>
        /// <returns> The local machine's IPv4 address if any, 127.0.0.1 on failure. </returns>
        public static IPAddress GetLocalEndpoint()
        {
            List <NetworkInterface> netInterfaces = new List <NetworkInterface>();

            try
            {
                netInterfaces = NetworkInterface.GetAllNetworkInterfaces()
                                .Where(n => n.Supports(NetworkInterfaceComponent.IPv4) && n.OperationalStatus == OperationalStatus.Up)
                                .ToList();
            }
            catch (NetworkInformationException netEx)
            {
                SkaiaLogger.LogMessage(MessageType.Critical, "Cannot get information about the network interfaces on this machine.", netEx);
                return(null);
            }

            if (netInterfaces.Count == 0)
            {
                // Well. Umm how can I say it. You ain't playing multiplayer at this point.
                SkaiaLogger.LogMessage(MessageType.Critical, "Cannot find any operating network interface with IPv4 support, defaulting to 127.0.0.1");

                // TODO: Check if we should just fail at this point, dunno if 127.0.0.1 will even work.
                return(IPAddress.Parse("127.0.0.1"));
            }

            IPAddress address = netInterfaces.Select(n => n.GetIPProperties())
                                .SelectMany(i => i.UnicastAddresses)
                                .Where(u => u.IsDnsEligible) // Just a safety check I suppose.
                                .Select(u => u.Address)
                                .FirstOrDefault();

            // Shouldn't ever arrive but you're never sure enough.
            // TODO: Again maybe check if we should just fail at this point.
            if (address == null)
            {
                return(IPAddress.Parse("127.0.0.1"));
            }

            return(address);
        }