Пример #1
0
        void fMain_Load(object sender, EventArgs e)
        {
            TryReadOptions();

            // 只有普通用户才能选择启用 UPnP
            KeiGuiOptions.Current.UsePortMapping = KeiGuiOptions.Current.UsePortMapping && !KeiGuiOptions.Current.IsPointInsertion;
            PortMapping.UsePortMapping           = KeiGuiOptions.Current.UsePortMapping;
            //if (KeiGuiOptions.Current.UseUPnP)
            //{
            //    ManagedUPnP.WindowsFirewall.CheckUPnPFirewallRules(this);
            //}

            if (KeiGuiOptions.Current.IsPointInsertion)
            {
                Text = Text + " (接入点)";
            }

            // 接入点是禁止通过路由的
            if (!KeiGuiOptions.Current.IsPointInsertion && KeiGuiOptions.Current.UsePortMapping)
            {
                cmdStartServers.Enabled = false;
                SetStatusText("初始化端口映射...");
                Thread t = new Thread(delegate()
                {
                    //PortMapping.InitUPnP(TimeSpan.FromSeconds(20));
                    PortMapping.InitializePortMappingEnvironment(TimeSpan.FromSeconds(5));
                    KeiGuiOptions.Current.UsePortMapping = KeiGuiOptions.Current.UsePortMapping && PortMapping.CanUsePortMapping;
                    label1.Visible = KeiGuiOptions.Current.UsePortMapping;
                    cboPossibleAddresses.Visible = KeiGuiOptions.Current.UsePortMapping;
                    // HACK: HACK
                    label1.Visible = cboPossibleAddresses.Visible = false;
                    if (KeiGuiOptions.Current.UsePortMapping)
                    {
                        SetStatusText("就绪");
                    }
                    else
                    {
                        SetStatusText("就绪 (端口映射不可用)");
                    }
                    cmdStartServers.Enabled = true;
                });
                t.IsBackground = true;
                t.Start();
            }
            else
            {
                SetStatusText("就绪");
            }

            // 如果这只小白鼠(例如我)愿意做接入点的话……那就给ta选吧
            // 设置界面项:如果是接入点(高级用户)或者是要使用 UPnP 的用户,则应该显示本地地址
            if (KeiGuiOptions.Current.IsPointInsertion || (false && KeiGuiOptions.Current.UsePortMapping))
            {
                //var possibleAddresses = Dns.GetHostEntry(IPAddress.Loopback).AddressList;
                //foreach (var address in possibleAddresses)
                //{
                //    if (address.AddressFamily == AddressFamily.InterNetwork && IPUtil.IsAddressIntranet(address))
                //    {
                //        cboPossibleAddresses.Items.Add(address.ToString());
                //    }
                //}

                var ifs = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
                foreach (var face in ifs)
                {
                    switch (face.NetworkInterfaceType)
                    {
                    case System.Net.NetworkInformation.NetworkInterfaceType.Ethernet:
                    case System.Net.NetworkInformation.NetworkInterfaceType.Ethernet3Megabit:
                    case System.Net.NetworkInformation.NetworkInterfaceType.FastEthernetFx:
                    case System.Net.NetworkInformation.NetworkInterfaceType.FastEthernetT:
                    case System.Net.NetworkInformation.NetworkInterfaceType.Fddi:
                    case System.Net.NetworkInformation.NetworkInterfaceType.GigabitEthernet:
                    case System.Net.NetworkInformation.NetworkInterfaceType.Wireless80211:
                        if (face.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up)
                        {
                            var p = face.GetIPProperties();
                            if (p.UnicastAddresses.Count > 0)
                            {
                                foreach (var a in p.UnicastAddresses)
                                {
                                    if (a.Address.AddressFamily == AddressFamily.InterNetwork && KeiUtil.IsAddressIntranet(a.Address))
                                    {
                                        cboPossibleAddresses.Items.Add(a.Address.ToString() + " [" + face.Name + "]");
                                    }
                                }
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }

                // 调整 combobox 的下拉宽度
                if (cboPossibleAddresses.Items.Count > 0)
                {
                    SizeF maxSizeF = SizeF.Empty;
                    using (var g = cboPossibleAddresses.CreateGraphics())
                    {
                        foreach (var item in cboPossibleAddresses.Items)
                        {
                            var s = g.MeasureString((string)item, cboPossibleAddresses.Font);
                            if (s.Width > maxSizeF.Width)
                            {
                                maxSizeF = s;
                            }
                        }
                    }
                    cboPossibleAddresses.DropDownWidth = (int)Math.Ceiling(maxSizeF.Width);
                }

                if (cboPossibleAddresses.Items.Count > 0)
                {
                    int  foundIndex = -1;
                    int  i          = 0;
                    bool found      = false;
                    foreach (var item in cboPossibleAddresses.Items)
                    {
                        if (((string)item).StartsWith(KeiGuiOptions.Current.LocalIntranetAddress))
                        {
                            found      = true;
                            foundIndex = i;
                            break;
                        }
                        i++;
                    }
                    if (found)
                    {
                        cboPossibleAddresses.SelectedIndex = foundIndex;
                    }
                    else
                    {
                        cboPossibleAddresses.SelectedIndex = 0;
                    }
                }
                else
                {
                    MessageBox.Show("在您的计算机上没有找到合适的内网地址,将无法正常启动。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                label1.Visible = false;
                cboPossibleAddresses.Visible = false;
            }
            // 设置界面项:如果是普通用户,就不需要知道本地的客户端端点了
            if (!KeiGuiOptions.Current.IsPointInsertion)
            {
                label5.Visible = false;
                txtLocalKClientEndPoint.Visible = false;
            }
            // 设置界面项:如果是接入点,则“连接”框都可以免去了
            if (false && KeiGuiOptions.Current.IsPointInsertion)
            {
                groupBox2.Visible = false;
            }

            foreach (var item in KeiGuiOptions.Current.TargetEndPoints)
            {
                cboTargetKClientEndPoint.Items.Add(item);
            }
            // 暂时不要自动切换到第0项,要不然我的机子就爆炸了……

            groupBox2.Enabled           = false;
            mnuOpForceBroadcast.Enabled = false;
            ctxForceBroadcast.Enabled   = false;

            notifier.Icon        = this.Icon;
            notifier.ContextMenu = ctxMenu;
            notifier.Text        = Application.ProductName;
            notifier.Visible     = true;
        }
Пример #2
0
 void cmdConnectToTargetKClient_Click(object sender, EventArgs e)
 {
     try
     {
         IPEndPoint ipep = KeiUtil.ParseIPEndPoint(cboTargetKClientEndPoint.Text);
         Thread     kcWorkerThread;
         for (var i = 0; i < 1; i++)
         {
             //Thread.Sleep(1500);
             WaitHandle wh;
             if (KeiGuiOptions.Current.IsPointInsertion)
             {
                 wh = _kClient.EnterNetwork(ipep, Convert.ToUInt16(txtLocalKClientPort.Text), out kcWorkerThread);
             }
             else
             {
                 // 普通用户
                 wh = _kClient.EnterNetwork(ipep, 0, out kcWorkerThread);
             }
             Thread thread = new Thread(delegate()
             {
                 Invoke(new Action(() =>
                 {
                     cmdConnectToTargetKClient.Enabled = false;
                 }));
                 TimeSpan passedTime = TimeSpan.Zero;
                 while (kcWorkerThread.IsAlive && !wh.SafeWaitHandle.IsClosed && passedTime < TimeSpan.FromSeconds(3))
                 {
                     wh.WaitOne(TimeSpan.FromMilliseconds(10));
                     passedTime += TimeSpan.FromMilliseconds(10);
                 }
                 if (_kClient.ConnectionList.Count > 0)
                 {
                     Invoke(new Action(() =>
                     {
                         if (!_kClient.IsActive)
                         {
                             // 普通用户此时启动
                             // 不过确实,想想,对于普通用户,如果是端口在从 TestBind() 到现在(即,点下“启动”按钮到点下“连接”按钮并成功)
                             // 这段时间内,该K客户端端口被占用了怎么办?这里就会直接异常,线程崩溃了……
                             _kClient.Listen();
                         }
                         cmdConnectToTargetKClient.Enabled = false;
                         groupBox2.Enabled = false;
                         KGState           = KeiGuiState.Connected;
                         if (!cboTargetKClientEndPoint.Items.Contains(cboTargetKClientEndPoint.Text))
                         {
                             cboTargetKClientEndPoint.Items.Add(cboTargetKClientEndPoint.Text);
                         }
                         SetStatusText("已经连接到 " + cboTargetKClientEndPoint.Text + ",开始工作 [" + _kClient.ConnectionList.Count.ToString() + "]");
                         mnuOpForceBroadcast.Enabled = true;
                         ctxForceBroadcast.Enabled   = true;
                     }));
                 }
                 else
                 {
                     Invoke(new Action(() =>
                     {
                         cmdConnectToTargetKClient.Enabled = true;
                         SetStatusText("未能连接到 " + cboTargetKClientEndPoint.Text);
                     }));
                 }
             });
             thread.IsBackground = true;
             thread.Start();
         }
     }
     catch (Exception ex)
     {
         Program.Logger.Log(ex.Message);
     }
 }