private void ListenUDP() { ThreadUDPListen = new Thread(new ThreadStart(delegate { while (UDPListen) { try { IPEndPoint EP = LocalClientInfo.InternalEndpoint; if (EP != null) { byte[] ReceivedBytes = UDPClient.Receive(ref EP); IP2PBase Item = ReceivedBytes.ToP2PBase(); ProcessItem(Item, EP); } } catch (Exception e) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Error on UDP Receive: " + e.Message); } } } })); ThreadUDPListen.IsBackground = true; if (UDPListen) { ThreadUDPListen.Start(); } }
public void ConnectToClient(ClientInfo CI) { Req R = new Req(LocalClientInfo.ID, CI.ID); SendMessageTCP(R); if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Sent Connection Request To: " + CI.ToString()); } Thread Connect = new Thread(new ThreadStart(delegate { IPEndPoint ResponsiveEP = FindReachableEndpoint(CI); if (ResponsiveEP != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Connection Successfull to: " + ResponsiveEP.ToString()); } if (OnClientConnection != null) { OnClientConnection.Invoke(CI, ResponsiveEP); } } })); Connect.IsBackground = true; Connect.Start(); }
public void ClearUpUPnP() { if (UPnPMappings != null) { List <int> PortMappingsToDelete = new List <int>(); foreach (IStaticPortMapping map in UPnPMappings) { try { //if (map.Protocol == "UDP" && map.Description == "P2P Chat" && map.InternalClient == InternetAccessAdapter.ToString()) // PortMappingsToDelete.Add(map.ExternalPort); if (map.Protocol == "UDP" && map.Description == "DataDepositer P2P" && map.InternalClient == InternetAccessAdapter.ToString()) { PortMappingsToDelete.Add(map.ExternalPort); } } catch { } } foreach (int port in PortMappingsToDelete) { try { UPnPMappings.Remove(port, "UDP"); if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "UPnP Map " + port + " Removed"); } } catch (Exception ex) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Failed to remove UPnP Map " + port + ": " + ex.Message); } } } } }
public void SendMessageTCP(IP2PBase Item) { if (TCPClient.Connected) { byte[] Data = Item.ToByteArray(); try { NetworkStream NetStream = TCPClient.GetStream(); NetStream.Write(Data, 0, Data.Length); } catch (Exception e) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Error on TCP Send: " + e.Message); } } } }
public void SendMessageUDP(IP2PBase Item, IPEndPoint EP) { Item.ID = LocalClientInfo.ID; byte[] data = Item.ToByteArray(); try { if (data != null) { UDPClient.Send(data, data.Length, EP); } } catch (Exception e) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Error on UDP Send: " + e.Message); } } }
private void ListenTCP() { ThreadTCPListen = new Thread(new ThreadStart(delegate { byte[] ReceivedBytes = new byte[4096]; int BytesRead = 0; while (TCPListen) { try { BytesRead = TCPClient.GetStream().Read(ReceivedBytes, 0, ReceivedBytes.Length); if (BytesRead == 0) { break; } else { IP2PBase Item = ReceivedBytes.ToP2PBase(); ProcessItem(Item); } } catch (Exception e) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Error on TCP Receive: " + e.Message); } } } })); ThreadTCPListen.IsBackground = true; if (TCPListen) { ThreadTCPListen.Start(); } }
public void ConnectOrDisconnect() { if (TCPClient.Connected) { TCPClient.Client.Disconnect(true); UDPListen = false; TCPListen = false; Clients.Clear(); if (UPnPEnabled) { ClearUpUPnP(); } if (OnServerDisconnect != null) { OnServerDisconnect.Invoke(this, new EventArgs()); } if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Disconnected."); } } else { try { InternetAccessAdapter = GetAdapterWithInternetAccess(); if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Adapter with Internet Access: " + InternetAccessAdapter); } TCPClient = new TcpClient(); TCPClient.Client.Connect(ServerEndpoint); UDPListen = true; TCPListen = true; SendMessageUDP(LocalClientInfo.Simplified(), ServerEndpoint); LocalClientInfo.InternalEndpoint = (IPEndPoint)UDPClient.Client.LocalEndPoint; if (UPnPEnabled) { UPnPMappings = UPnPNAT.StaticPortMappingCollection; ClearUpUPnP(); if (LocalClientInfo.InternalEndpoint != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "UDP Listening on Port " + LocalClientInfo.InternalEndpoint.Port); } if (AttemptUPnP(LocalClientInfo.InternalEndpoint.Port)) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "UPnP Map Added"); } LocalClientInfo.UPnPEnabled = true; } else { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "UPnP Mapping Not Possible"); } } } } Thread.Sleep(500); SendMessageTCP(LocalClientInfo); Thread KeepAlive = new Thread(new ThreadStart(delegate { while (TCPClient.Connected) { Thread.Sleep(5000); SendMessageTCP(new KeepAlive()); } })); KeepAlive.IsBackground = true; KeepAlive.Start(); if (OnServerConnect != null) { OnServerConnect.Invoke(this, new EventArgs()); } } catch (Exception ex) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Error when connecting " + ex.Message); } } } }
private IPEndPoint FindReachableEndpoint(ClientInfo CI) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Attempting to Connect via LAN"); } for (int ip = 0; ip < CI.InternalAddresses.Count; ip++) { if (!TCPClient.Connected) { break; } IPAddress IP = CI.InternalAddresses[ip]; IPEndPoint EP = new IPEndPoint(IP, CI.InternalEndpoint.Port); for (int i = 1; i < 4; i++) { if (!TCPClient.Connected) { break; } if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Sending Ack to " + EP.ToString() + ". Attempt " + i + " of 3"); } SendMessageUDP(new Ack(LocalClientInfo.ID), EP); Thread.Sleep(200); Ack Responce = AckResponces.FirstOrDefault(a => a.RecipientID == CI.ID); if (Responce != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Received Ack Responce from " + EP.ToString()); } CI.ConnectionType = ConnectionTypes.LAN; AckResponces.Remove(Responce); return(EP); } } } if (CI.ExternalEndpoint != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Attempting to Connect via Internet"); } for (int i = 1; i < 100; i++) { if (!TCPClient.Connected) { break; } if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Sending Ack to " + CI.ExternalEndpoint + ". Attempt " + i + " of 99"); } SendMessageUDP(new Ack(LocalClientInfo.ID), CI.ExternalEndpoint); Thread.Sleep(300); Ack Responce = AckResponces.FirstOrDefault(a => a.RecipientID == CI.ID); if (Responce != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Received Ack New from " + CI.ExternalEndpoint.ToString()); } CI.ConnectionType = ConnectionTypes.WAN; AckResponces.Remove(Responce); return(CI.ExternalEndpoint); } } if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Connection to " + CI.Name + " failed"); } } else { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Client's External EndPoint is Unknown"); } } return(null); }
private void ProcessItem(IP2PBase Item, IPEndPoint EP = null) { if (Item.GetType() == typeof(Message)) { Message m = (Message)Item; ClientInfo CI = Clients.FirstOrDefault(x => x.ID == Item.ID); if (m.ID == 0) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, m.From + ": " + m.Content); } } if (m.ID != 0 & EP != null & CI != null) { if (OnMessageReceived != null) { OnMessageReceived.Invoke(EP, new MessageReceivedEventArgs(CI, m, EP)); } } } else if (Item.GetType() == typeof(ClientInfo)) { ClientInfo CI = Clients.FirstOrDefault(x => x.ID == Item.ID); if (CI == null) { Clients.Add((ClientInfo)Item); if (OnClientAdded != null) { OnClientAdded.Invoke(this, (ClientInfo)Item); } } else { CI.Update((ClientInfo)Item); if (OnClientUpdated != null) { OnClientUpdated.Invoke(this, (ClientInfo)Item); } } } else if (Item.GetType() == typeof(Notification)) { Notification N = (Notification)Item; if (N.Type == NotificationsTypes.Disconnected) { ClientInfo CI = Clients.FirstOrDefault(x => x.ID == long.Parse(N.Tag.ToString())); if (CI != null) { if (OnClientRemoved != null) { OnClientRemoved.Invoke(this, CI); } Clients.Remove(CI); } } else if (N.Type == NotificationsTypes.ServerShutdown) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Server shutting down."); } ConnectOrDisconnect(); } } else if (Item.GetType() == typeof(Req)) { Req R = (Req)Item; ClientInfo CI = Clients.FirstOrDefault(x => x.ID == R.ID); if (CI != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Received Connection Request from: " + CI.ToString()); } IPEndPoint ResponsiveEP = FindReachableEndpoint(CI); if (ResponsiveEP != null) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Connection Successfull to: " + ResponsiveEP.ToString()); } if (OnClientConnection != null) { OnClientConnection.Invoke(CI, ResponsiveEP); } if (OnClientUpdated != null) { OnClientUpdated.Invoke(this, CI); } } } } else if (Item.GetType() == typeof(Ack)) { Ack A = (Ack)Item; if (A.Responce) { AckResponces.Add(A); } else { ClientInfo CI = Clients.FirstOrDefault(x => x.ID == A.ID); if (CI.ExternalEndpoint.Address.Equals(EP.Address) & CI.ExternalEndpoint.Port != EP.Port) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Received Ack on Different Port (" + EP.Port + "). Updating ..."); } CI.ExternalEndpoint.Port = EP.Port; if (OnClientUpdated != null) { OnClientUpdated.Invoke(this, CI); } } List <string> IPs = new List <string>(); CI.InternalAddresses.ForEach(new Action <IPAddress>(delegate(IPAddress IP) { IPs.Add(IP.ToString()); })); if (!CI.ExternalEndpoint.Address.Equals(EP.Address) & !IPs.Contains(EP.Address.ToString())) { if (OnResultsUpdate != null) { OnResultsUpdate.Invoke(this, "Received Ack on New Address (" + EP.Address + "). Updating ..."); } CI.InternalAddresses.Add(EP.Address); } A.Responce = true; A.RecipientID = LocalClientInfo.ID; SendMessageUDP(A, EP); } } }