示例#1
0
        IEnumerable <StunResult> QueryByServers()
        {
            // 如果是被屏蔽,很有可能是因为服务器没有响应,可以通过轮换服务器来测试
            StunResult result = null;

            foreach (var item in Servers)
            {
                WriteLog("使用服务器:{0}", item);

                //Int32 p = item.IndexOf(":");
                //if (p > 0)
                //    result = QueryWithServer(item.Substring(0, p), Int32.Parse(item.Substring(p + 1)));
                //else
                //    result = QueryWithServer(item, 3478);
                var ep = NetHelper.ParseEndPoint(item, 3478);
                try
                {
                    result = QueryWithServer(ep.Address, ep.Port);
                }
                catch { result = null; }

                yield return(result);
            }
        }
示例#2
0
        /// <summary>确保建立服务器</summary>
        public override void EnsureCreateServer()
        {
            if (Servers.Count <= 0)
            {
                // 同时两个端口
                AddServer(IPAddress.Any, Port, ProtocolType.Unknown, AddressFamily.InterNetwork);
                AddServer(IPAddress.Any, Port2, ProtocolType.Unknown, AddressFamily.InterNetwork);

                var        dic = new Dictionary <Int32, IPEndPoint>();
                IPEndPoint ep  = null;
                var        pub = NetHelper.MyIP();
                StunResult rs  = null;
                WriteLog("获取公网地址……");

                foreach (var item in Servers)
                {
                    if (item.Local.ProtocolType == ProtocolType.Tcp)
                    {
                        continue;
                    }

                    // 查询公网地址和网络类型,如果是受限网络,或者对称网络,则采用本地端口,因此此时只能依赖端口映射,将来这里可以考虑操作UPnP
                    if (rs == null)
                    {
                        item.Start();
                        rs = new StunClient(item).Query();
                        if (rs != null)
                        {
                            if (rs != null && rs.Type == StunNetType.Blocked && rs.Public != null)
                            {
                                rs.Type = StunNetType.Symmetric;
                            }
                            WriteLog("网络类型:{0} {1}", rs.Type, rs.Type.GetDescription());
                            ep = rs.Public;
                            if (ep != null)
                            {
                                pub = ep.Address;
                            }
                        }
                    }
                    else
                    {
                        ep = new StunClient(item).GetPublic();
                    }
                    if (rs != null && rs.Type > StunNetType.AddressRestrictedCone)
                    {
                        ep = new IPEndPoint(pub, item.Port);
                    }
                    WriteLog("{0}的公网地址:{1}", item.Local, ep);
                    dic.Add(item.Port, ep);
                }
                // Tcp没办法获取公网地址,只能通过Udp获取到的公网地址加上端口形成,所以如果要使用Tcp,服务器必须拥有独立公网地址
                foreach (var item in Servers)
                {
                    if (item.Local.ProtocolType != ProtocolType.Tcp)
                    {
                        continue;
                    }

                    ep = new IPEndPoint(pub, item.Port);
                    WriteLog("{0}的公网地址:{1}", item.Local, ep);
                    dic.Add(item.Port + 100000, ep);
                }
                //var ep = StunClient.GetPublic(Port, 2000);
                //WriteLog("端口{0}的公网地址:{1}", Port, ep);
                //dic.Add(Port, ep);
                //ep = StunClient.GetPublic(Port2, 2000);
                //WriteLog("端口{0}的公网地址:{1}", Port2, ep);
                //dic.Add(Port2, ep);
                WriteLog("成功获取公网地址!");
                Public = dic;
            }
        }