Example #1
0
        protected override async void ReadAsync()
        {
            int milliseconds = 0;

            int i = 0;

            while (true)
            {
                milliseconds = 0;

                try
                {
                    while (true)
                    {
                        for (i = i; i < Players.Count; i++)
                        {
                            // TODO:  Cache these objects to save on garbage collection
                            DataReader reader = new DataReader(((StreamSocket)Players[i].SocketEndpoint).InputStream);

                            if (reader.UnconsumedBufferLength > 0)
                            {
                                byte[] bytes       = null;
                                uint   messageSize = await reader.LoadAsync(sizeof(uint));

                                if (messageSize != sizeof(uint))
                                {
                                    Disconnect();

                                    // socket was closed
                                    return;
                                }

                                bytes = new byte[messageSize];
                                reader.ReadBytes(bytes);
                                messageSize = BitConverter.ToUInt32(bytes, 0);
                                await reader.LoadAsync(messageSize);

                                bytes = new byte[messageSize];

                                // TODO:  This may read the first 4 bytes again for the size, make sure it doesn't
                                reader.ReadBytes(bytes);

                                readBuffer.Clone(bytes);
                                NetworkingStream stream = new NetworkingStream().Consume(this, Players[i], readBuffer);

                                DataRead(Players[i], stream);

                                // Write what was read to all the clients
                                Write(new NetworkingStream(stream.ProtocolType).Prepare(this, stream.identifierType, stream.NetworkedBehavior.NetworkedId, stream.Bytes));
                            }
                        }

                        i = 0;
                    }
                }
                catch (Exception e)
                {
                    ClientDisconnected(i);
                    //Networking.Error(e.Message);
                }

                await Task.Delay(ThreadSpeed);
            }
        }
Example #2
0
        /// <summary>
        /// This method is used on the client to attempt to connect to the server through the NAT hole punch server
        /// </summary>
        /// <param name="socket">This is the socket that is being used for the communication with the server</param>
        /// <param name="port">This is the port number that this client is bound to</param>
        /// <param name="requestHost">This is the host address of the server that this client is trying to connect to</param>
        /// <param name="requestPort">This is the host port of the server that this client is trying to connect to</param>
        /// <param name="proxyHost">This is the NAT hole punch server host address</param>
        /// <param name="proxyPort">This is the NAT hole punch server port number</param>
        /// <returns></returns>
        public static bool RequestNat(NetWorker socket, ushort port, string requestHost, ushort requestPort, string proxyHost, ushort proxyPort = PORT)
        {
#if !NetFX_CORE && !UNITY_WEBGL
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(proxyHost), proxyPort);

            List <byte> data = new List <byte>(new byte[] { 4, 4, 2 });
            data.AddRange(BitConverter.GetBytes(port));
            data.AddRange(BitConverter.GetBytes(requestPort));
            data.AddRange(Encryptor.Encoding.GetBytes(requestHost));

            try
            {
                int tryCount = 10;
                while (((CrossPlatformUDP)socket).ReadClient.Available == 0)
                {
                    ((CrossPlatformUDP)socket).ReadClient.Send(data.ToArray(), data.Count, endpoint);
                    Thread.Sleep(500);

                    if (--tryCount <= 0)
                    {
                        throw new Exception("Unable to contact proxy host");
                    }
                }

                string  endpointStr = "";
                BMSByte otherBytes  = ((CrossPlatformUDP)socket).ReadClient.Receive(ref endpoint, ref endpointStr);

                BMSByte found = new BMSByte();
                found.Clone(otherBytes);

                if (found.byteArr[2] == 0)
                {
                    return(false);
                }

                ushort targetPort = System.BitConverter.ToUInt16(found.byteArr, 3);
                string targetHost = Encryptor.Encoding.GetString(found.byteArr, 5, found.byteArr.Length - 6);

                IPEndPoint targetEndpoint = new IPEndPoint(IPAddress.Parse(targetHost), targetPort);

                tryCount = 20;
                while (((CrossPlatformUDP)socket).ReadClient.Available == 0)
                {
                    ((CrossPlatformUDP)socket).ReadClient.Send(new byte[] { 4, 4, 0 }, 3, targetEndpoint);
                    Thread.Sleep(500);

                    if (--tryCount <= 0)
                    {
                        throw new Exception("Unable to contact proxy host");
                    }
                }

#if UNITY_EDITOR
                Debug.Log("Connected via NAT traversal");
#endif
            }
#if UNITY_EDITOR
            catch (Exception e)
            {
                Debug.LogException(e);
            }
#else
            catch { }
#endif
#endif

            return(true);
        }