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; }
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); } }