Пример #1
0
        /// <summary>
        /// Open up a port on the gateway.
        /// </summary>
        private void Open(int port, bool tcp, OnPortRequest callback)
        {
            int id = (port << 8) | (tcp ? 1 : 0);

            if (port > 0 && !mPorts.Contains(id) && mStatus != Status.Failure)
            {
                ListLessGarb <IPAddress> debug = NetworkUtility.localAddresses;

                if (mDiscover == null)
                {
                    mDiscover = new Thread(ThreadDiscover);
                    mThreads.Add(mDiscover);
                    mDiscover.Start(mDiscover);
                }

                string addr = NetworkUtility.localAddress.ToString();
                if (addr == "127.0.0.1")
                {
                    return;
                }

                mPorts.Add(id);

                ExtraParams xp = new ExtraParams();
                xp.callback = callback;
                xp.port     = port;
                xp.protocol = tcp ? ProtocolType.Tcp : ProtocolType.Udp;
                xp.action   = "AddPortMapping";
                xp.request  = "<NewRemoteHost></NewRemoteHost>\n" +
                              "<NewExternalPort>" + port + "</NewExternalPort>\n" +
                              "<NewProtocol>" + (tcp ? "TCP" : "UDP") + "</NewProtocol>\n" +
                              "<NewInternalPort>" + port + "</NewInternalPort>\n" +
                              "<NewInternalClient>" + addr + "</NewInternalClient>\n" +
                              "<NewEnabled>1</NewEnabled>\n" +
                              "<NewPortMappingDescription>" + name + "</NewPortMappingDescription>\n" +
                              "<NewLeaseDuration>0</NewLeaseDuration>\n";

                xp.th = new Thread(OpenRequest);
                lock (mThreads)
                {
                    mThreads.Add(xp.th);
                }

                xp.th.Start(xp);

                Debug.Log("[UPnP:Open(" + port + ", " + (tcp ? "TCP" : "UDP") + ")] -> Requested");
            }
            else if (callback != null)
            {
                callback(this, port, tcp ? ProtocolType.Tcp : ProtocolType.Udp, false);
            }
        }
Пример #2
0
        /// <summary>
        /// Start listening for incoming messages on the specified port.
        /// </summary>
        public bool Start(int port, bool multiThreaded = true)
        {
            this.multiThreaded = multiThreaded;
            Stop();

            Port   = port;
            Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Web player doesn't seem to support broadcasts
            Socket.MulticastLoopback = true;
            multicast = useMulticasting;

            try
            {
                if (useMulticasting)
                {
                    ListLessGarb <IPAddress> ips = NetworkUtility.localAddresses;

                    foreach (IPAddress ip in ips)
                    {
                        MulticastOption opt = new MulticastOption(multicastIP, ip);
                        Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, opt);
                    }
                }
                else
                {
                    Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            // Port zero means we will be able to send, but not receive
            if (Port == 0)
            {
#if DEBUG
                Debug.Log("[UdpProtocol:Start(" + port +
                          ") - Port zero means we will be able to send, but not receive");
#endif
                return(true);
            }

            try
            {
                // Use the default network interface if one wasn't explicitly chosen
#if (UNITY_IPHONE && !UNITY_EDITOR) //|| UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
                IPAddress networkInterface = useMulticasting ? multicastIP : (defaultNetworkInterface ?? IPAddress.Any);
#else
                IPAddress networkInterface = defaultNetworkInterface ?? IPAddress.Any;
#endif
                endPoint        = new IPEndPoint(networkInterface, 0);
                defaultEndPoint = new IPEndPoint(networkInterface, 0);

                // Bind the socket to the specific network interface and start listening for incoming packets
                Socket.Bind(new IPEndPoint(networkInterface, Port));
                Socket.BeginReceiveFrom(temp, 0, temp.Length, SocketFlags.None, ref endPoint, OnReceive, null);
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
                Stop();
                return(false);
            }

            if (multiThreaded)
            {
                thread = new Thread(ThreadProcessPackets);
                thread.Start();
            }

#if DEBUG
            Debug.Log("[UdpProtocol:Start(" + port + ") - Success ! useMulticasting? " + useMulticasting +
                      " EndPoint: " + endPoint);
#endif
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Gateway lobby logic is done on a separate thread so that it's not blocking the main thread.
        /// </summary>
        private void ThreadDiscover(object obj)
        {
            Thread th = (Thread)obj;

            string request = "M-SEARCH * HTTP/1.1\r\n" +
                             "HOST: 239.255.255.250:1900\r\n" +
                             "ST:upnp:rootdevice\r\n" +
                             "MAN:\"ssdp:discover\"\r\n" +
                             "MX:3\r\n\r\n";

            byte[] requestBytes          = Encoding.ASCII.GetBytes(request);
            int    port                  = 10000 + (int)(DateTime.UtcNow.Ticks % 45000);
            ListLessGarb <IPAddress> ips = NetworkUtility.localAddresses;

            Debug.Log("[UPnP:ThreadDiscover()] -> Running. Status: " + mStatus + " | IPs count: " + ips.Count);

            // UPnP discovery should happen on all network interfaces
            for (int i = 0; i < ips.size; ++i)
            {
                IPAddress ip = ips[i];
                mStatus = Status.Searching;
                UdpClient receiver = null;

                try
                {
                    UdpClient sender = new UdpClient(new IPEndPoint(ip, port));

                    sender.Connect(IPAddress.Broadcast, 1900);
                    sender.Send(requestBytes, requestBytes.Length);
                    sender.Close();

                    receiver = new UdpClient(new IPEndPoint(ip, port));
                    receiver.Client.ReceiveTimeout = 3000;

                    IPEndPoint sourceAddress = new IPEndPoint(IPAddress.Any, 0);

                    for (;;)
                    {
                        byte[] data = receiver.Receive(ref sourceAddress);

                        if (ParseResponse(Encoding.ASCII.GetString(data, 0, data.Length)))
                        {
                            receiver.Close();

                            lock (mThreads)
                            {
                                mGatewayAddress = sourceAddress.Address;
#if UNITY_EDITOR
                                Debug.Log("[TNet] UPnP Gateway: " + mGatewayAddress);
#endif
                                mStatus = Status.Success;
                                mThreads.Remove(th);
                            }

                            mDiscover = null;
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                }

                if (receiver != null)
                {
                    receiver.Close();
                }

                lock (mThreads)
                {
                    mStatus = Status.Failure;
                    mThreads.Remove(th);
                }

                mDiscover = null;

                // If we found one, we're done
                if (mStatus == Status.Success)
                {
                    break;
                }
            }

            if (mStatus != Status.Success)
            {
                Debug.LogWarning(
                    "[UPnP:ThreadDiscover()] -> UPnP discovery failed. TNet won't be able to open ports automatically.");
            }
        }