/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { this.State = PeerToPeerNetworkState.Closed; if (this.tcpListener != null) { this.tcpListener.Stop(); this.tcpListener = null; } if (this.tcpMappingAdded) { this.tcpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "TCP"); } catch (Exception) { // Ignore } } if (this.udpMappingAdded) { this.udpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "UDP"); } catch (Exception) { // Ignore } } this.serviceWANIPConnectionV1 = null; if (this.upnpClient != null) { this.upnpClient.Dispose(); this.upnpClient = null; } if (this.ipAddressesFound != null) { this.ipAddressesFound.Clear(); this.ipAddressesFound = null; } if (this.ready != null) { this.ready.Close(); this.ready = null; } if (this.error != null) { this.error.Close(); this.error = null; } }
private void ServiceRetrieved(object Sender, ServiceDescriptionEventArgs e) { try { DeviceLocationEventArgs e2 = (DeviceLocationEventArgs)e.State; Dictionary<ushort, bool> TcpPortMapped = new Dictionary<ushort, bool>(); Dictionary<ushort, bool> UdpPortMapped = new Dictionary<ushort, bool>(); string NewExternalIPAddress; ushort PortMappingIndex; string NewRemoteHost; ushort NewExternalPort; string NewProtocol; ushort NewInternalPort; string NewInternalClient; bool NewEnabled; string NewPortMappingDescription; uint NewLeaseDuration; this.serviceWANIPConnectionV1 = new WANIPConnectionV1(e.ServiceDescriptionDocument); this.State = PeerToPeerNetworkState.RegisteringApplicationInGateway; this.serviceWANIPConnectionV1.GetExternalIPAddress(out NewExternalIPAddress); this.externalAddress = IPAddress.Parse(NewExternalIPAddress); PortMappingIndex = 0; try { while (true) { this.serviceWANIPConnectionV1.GetGenericPortMappingEntry(PortMappingIndex, out NewRemoteHost, out NewExternalPort, out NewProtocol, out NewInternalPort, out NewInternalClient, out NewEnabled, out NewPortMappingDescription, out NewLeaseDuration); if (NewPortMappingDescription == this.applicationName && NewInternalClient == e2.LocalEndPoint.Address.ToString()) this.serviceWANIPConnectionV1.DeletePortMapping(NewRemoteHost, NewExternalPort, NewProtocol); else { switch (NewProtocol) { case "TCP": TcpPortMapped[NewExternalPort] = true; break; case "UDP": UdpPortMapped[NewExternalPort] = true; break; } PortMappingIndex++; } } } catch (UPnPException) { // No more entries. } this.localAddress = e2.LocalEndPoint.Address; ushort LocalPort; int i; do { this.tcpListener = new TcpListener(this.localAddress, this.desiredPort); this.tcpListener.Start(this.backlog); i = ((IPEndPoint)this.tcpListener.LocalEndpoint).Port; LocalPort = (ushort)(i); if (i < 0 || i > ushort.MaxValue || TcpPortMapped.ContainsKey(LocalPort) || UdpPortMapped.ContainsKey(LocalPort)) { this.tcpListener.Stop(); this.tcpListener = null; if (this.desiredPort != 0) throw new ArgumentException("Port already assigned to another application in the network.", "Port"); } else { try { this.udpClient = new UdpClient(this.tcpListener.LocalEndpoint.AddressFamily); this.udpClient.Client.Bind((IPEndPoint)this.tcpListener.LocalEndpoint); } catch (Exception) { this.tcpListener.Stop(); this.tcpListener = null; } } } while (this.tcpListener == null); this.localEndpoint = new IPEndPoint(this.localAddress, LocalPort); this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, LocalPort, "TCP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); this.tcpMappingAdded = true; this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, LocalPort, "UDP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); this.udpMappingAdded = true; this.externalEndpoint = new IPEndPoint(this.externalAddress, LocalPort); this.State = PeerToPeerNetworkState.Ready; this.tcpListener.BeginAcceptTcpClient(this.EndAcceptTcpClient, null); this.udpClient.BeginReceive(this.EndReceiveUdp, null); } catch (Exception ex) { this.exception = ex; this.State = PeerToPeerNetworkState.Error; } }