/// <summary> /// Settings für HierarchieServer. /// </summary> /// <param name="isRoot"></param> public static void HierarchieSettings(bool isRoot) { ServerConfig.structure = Structure.HIERARCHY; Console.WriteLine("HierarchieSettings"); if (isRoot) { ServerConfig.host = KnownServers.Root; // <- Sollte nur noch in KnownServers geändert werden ServerConfig.serverID = 1; } else { while (true) { Console.WriteLine("Stimmt die Adresse von Root? [Y/N]"); Console.WriteLine(KnownServers.Root); char answer; do { answer = (char)Console.Read(); } while (!"YyJjNn".Contains(answer)); if ("Nn".Contains(answer)) { do { Console.WriteLine("Bitte eine valide IPv4 Adresse für Root angeben."); } while (!IPAddress.TryParse(Console.ReadLine(), out KnownServers.Root)); } //read = Console.ReadLine(); Package package = new Package { sourceServer = ServerConfig.host.ToString(), hierarchie = new HierarchiePackage() }; package.hierarchie.HierarchieRequest = HierarchieRequest.NewServer; package = ServerLogic.Send(package, KnownServers.Root); if (package != null) { Console.WriteLine("Packet ist angekommen"); //Logic Console.WriteLine("Adresse: " + package.hierarchie.destinationAdress); //Zu wem muss ich mich verbinden? bzw. Registrieren package.hierarchie.HierarchieRequest = HierarchieRequest.RegisterServer; package.hierarchie.sourceAdress = ServerConfig.host.ToString(); Console.WriteLine("Verbindung zum Server aufbauen? Y"); Console.ReadLine(); IPAddress connectServer = IPAddress.Parse(package.hierarchie.destinationAdress); Package receive; while (true) { try { receive = ServerLogic.Send(package, connectServer); Thread.Sleep(1000); break; } catch (Exception ex) { Console.WriteLine("Es gab ein Problem. Y fuer nochmal"); Console.ReadLine(); Console.WriteLine(ex); } } if (receive != null) { Console.WriteLine("SourceID: " + receive.hierarchie.sourceID); ServerConfig.serverID = receive.hierarchie.sourceID; ServerLogic.database.NewServerEntry(receive.hierarchie.destinationAdress, receive.hierarchie.destinationID); Console.WriteLine("Adresse: " + receive.hierarchie.destinationAdress); Console.WriteLine("ID: " + receive.hierarchie.destinationID); break; } else { Console.WriteLine("Server antwortet nicht richtig, Root nochmal fragen"); } } else { Console.WriteLine("Server nicht verfügbar oder irgendwas ist schief gelaufen"); } } } }
/// <summary> /// Settings für P2PServer. Zugehöriigkeit WellKnownPeers usw. /// </summary> /// <param name="isWellKnown"></param> public static void P2PSettings(bool isWellKnown) { while (CheckWellKnownPeers()) { ; } if (isWellKnown) { //Data.ServerConfig.ListofWellKnown.Add(Data.ServerConfig.host); foreach (IPAddress ipAddress in KnownServers.ListofWellKnownPeers) { if (ipAddress.ToString() != ServerConfig.host.ToString()) { Package package = new Package { p2p = new P2PPackage() }; package.p2p.P2Prequest = P2PRequest.RegisterServer; package.p2p.SetOriginIPAddress(ServerConfig.host.ToString()); Package receive = ServerLogic.Send(package, ipAddress); //Nur hinzufügen wenn noch nicht existent if (receive != null && !ServerConfig.neighbours.Exists(x => x.ToString() == ipAddress.ToString())) { ServerConfig.neighbours.Add(ipAddress); } } } } else { //This only functions if we have two or more Well Known Peers for (int i = 2; i > 0; i--) //'i' represents number of connections to create. { Package package = new Package { p2p = new P2PPackage { P2Prequest = P2PRequest.NewServer }, sourceServer = ServerConfig.host.ToString() }; package.p2p.SetOriginIPAddress(ServerConfig.host.ToString()); package = ServerLogic.Send(package, KnownServers.GetRandomWellKnownPeer()); if (package != null) { //2 Server mit denen ich mich verbinde und bei denen Registriere switch (package.p2p.P2PAnswer) { case P2PAnswer.Error: Console.WriteLine(package.p2p.ErrorMsg); break; case P2PAnswer.Failure: Console.WriteLine(NewServerFail); break; default: Package registerPackage = new Package { p2p = new P2PPackage { P2Prequest = P2PRequest.RegisterServer }, sourceServer = ServerConfig.host.ToString() }; registerPackage.p2p.SetOriginIPAddress(ServerConfig.host.ToString()); registerPackage = ServerLogic.Send(registerPackage, IPAddress.Parse(package.p2p.lastIP)); if (registerPackage != null) { switch (registerPackage.p2p.P2PAnswer) { case P2PAnswer.Success: ServerConfig.neighbours.Add(IPAddress.Parse(package.p2p.lastIP)); Console.WriteLine(RegisterServerSuccess); break; case P2PAnswer.Visited: break; default: Console.WriteLine(RegisterServerFail); break; } } else { Console.WriteLine(SendError); } break; } } else { Console.WriteLine(SendError); } } } if (ServerConfig.neighbours.Count == 0) { Console.WriteLine(SetupFailed); } else if (ServerConfig.neighbours.Count < 2) { Console.WriteLine(SetupIncomplete); } else { Console.WriteLine(SetupComplete); } }
/// <summary> /// Paketauflösung in einem HierarchieNetz. /// </summary> /// <param name="package"></param> /// <returns></returns> public static HierarchiePackage ResolveHierarchie(HierarchiePackage package) { int anzConnection = ServerLogic.database.GetServerCount(); string ip = ServerConfig.host.ToString(); int id = ServerConfig.serverID; switch (package.HierarchieRequest) { case HierarchieRequest.Invite: //Ab hier soll man wissen, an WEN ES GEHEN SOLL UND MUSS! if (package.destinationID != ServerConfig.serverID) { sendHierarchie(getAdress(package.destinationID), ToDo.Send, null); } else { //TO FIX: Schau erstmal nach ob der User existiert if (ServerLogic.database.UserExist(package.login)) { ServerLogic.database.SaveInvites(package.login, package.invite); package.HierarchieAnswer = HierarchieAnswer.Success; } else { // TO FIX: User existiert nicht? } } break; case HierarchieRequest.NewServer: if (anzConnection > 0) { //Eigene Send funktion machen //Auch parallel //sendHierarchie(); Console.WriteLine("Auf der SUche nach einem passenden Server"); StateEintrag stateEintrag = new StateEintrag(); List <HierarchiePackage> child = new List <HierarchiePackage>(); stateEintrag.SetCounter(ServerLogic.database.GetServerCount()); int childcount = 0; for (int i = 0; i < ServerLogic.database.GetServerCount(); i++) { Console.WriteLine("Dieser Server hat Kinder"); int childID = ServerConfig.serverID * 10 + 1 - i; //Weil HierarchieID's! if (ServerLogic.database.ServerExist(childID)) { try { child.Add(sendHierarchie(getAdress(childID), ToDo.Info, stateEintrag)); childcount++; } catch (Exception) { Console.WriteLine("Etwas ist schief gelaufen beim KindServer"); } } } //wartet auf die anderen. hoffentlich //stateEintrag.wait(); if (childcount != 1) // wenn der Server nur ein Kind hat, so hat er das Sorgerecht für das Kind { //Wenn überhaupt was reingebracht wurde if (child.Count > 0) { foreach (HierarchiePackage c in child) { //wenn zuverlässigerweise was schief gelaufen ist, wird das ignoriert if (c != null) { if (c.anzConnection <= anzConnection) { anzConnection = c.anzConnection; ip = c.destinationAdress; id = c.destinationID; } } } } } } package.destinationID = id; package.destinationAdress = ip; package.anzConnection = anzConnection; //Muss ich weiterleiten an die Unter mir? oder Nicht? entsprechende Antwort schicken break; case HierarchieRequest.RegisterServer: //Sollte immer durch newServer abgefragt werden! Console.WriteLine("Ein neuer Servereintrag. bzw. Child"); int newId = ServerConfig.serverID * 10; //if (Data.ServerConfig.host == Data.ServerConfig.root) //{ // newId += 10; //} //if (database.getServerCount() == 0) //{ // newId += 1; //} if (!ServerLogic.database.ServerExist(newId + 1)) { newId += 1; } package.sourceID = newId; ServerLogic.database.NewServerEntry(package.sourceAdress, newId); break; case HierarchieRequest.RegisterUser: int anzUser = ServerLogic.database.GetUserCount(); //überprüfen ob USERNAME schon existiert! if (ServerLogic.database.UserExist(package.login)) { package.HierarchieAnswer = HierarchieAnswer.UserExistent; break; } else if (anzConnection > 0) { //Eigene Send funktion machen //Soll parallel ablaufen //sendHierarchie(); StateEintrag stateEintrag = new StateEintrag(); List <HierarchiePackage> child = new List <HierarchiePackage>(); stateEintrag.SetCounter(ServerLogic.database.GetServerCount()); for (int i = 0; i < 2; i++) { int childID = (ServerConfig.serverID * 10) + 1 - i; //Weil HierarchieID's! if (ServerLogic.database.ServerExist(childID)) { child.Add(sendHierarchie(getAdress(childID), ToDo.Info, stateEintrag)); } } //wartet auf die anderen. hoffentlich if (child.Count > 0) { child = stateEintrag.child; foreach (HierarchiePackage c in child) { if (c != null) { if (c.anzUser <= anzUser) { anzUser = c.anzUser; ip = c.destinationAdress; id = c.destinationID; } } } } } package.destinationID = id; package.destinationAdress = ip; package.anzUser = anzUser; package.HierarchieAnswer = HierarchieAnswer.Success; break; case HierarchieRequest.UserLogin: if (package.destinationID == id) { if (ServerLogic.database.UserExist(package.login)) { package.destinationAdress = ServerConfig.host.ToString(); package.HierarchieAnswer = HierarchieAnswer.Success; } else { package.HierarchieAnswer = HierarchieAnswer.Failure; } } else { package = sendHierarchie(getAdress(package.destinationID), ToDo.Send, null); } break; default: break; } string getAdress(int ask) { int numberask = GetDigitCount(ask); int numberid = GetDigitCount(id); bool isUp = false; int child = 0; if (numberid >= numberask) { isUp = true; } else { int dif = (int)(numberask - numberid); int level = (int)(ask / Math.Pow(10, dif)); //Bin ich das? if (level != id) { isUp = true; } else { child = (int)(ask / Math.Pow(10, dif - 1)); } } int addressid = id; if (isUp) { addressid /= 10; } else { addressid = child; } return(ServerLogic.database.GetServer(addressid)); } int GetDigitCount(int number) { if (number != 0) { double baseExp = Math.Log10(Math.Abs(number)); return(Convert.ToInt32(Math.Floor(baseExp) + 1)); } else { return(1); } } HierarchiePackage sendHierarchie(string ipadress, ToDo _toDo, StateEintrag state) { Package hierarchie = new Package { hierarchie = package }; //An beide Childs if (_toDo == ToDo.Info) { hierarchie = ServerLogic.Send(hierarchie, IPAddress.Parse(ipadress)); state.DecrementCounter(); state.child.Add(hierarchie.hierarchie); } else if (_toDo == ToDo.Send) //nur an einer gewissen Server { hierarchie = ServerLogic.Send(hierarchie, IPAddress.Parse(ipadress)); } return(hierarchie.hierarchie); } return(package); }
/// <summary> /// Das Handling von P2PPaketen. /// </summary> /// <param name="package"></param> /// <returns></returns> public static P2PPackage ResolveP2P(P2PPackage package) { if (ServerConfig.CheckPackageID(package.GetPackageID())) { try { List <P2PPackage> returnList; switch (package.P2Prequest) { case P2PRequest.NewServer: //0. Falls ich ihn noch nicht als Nachbarn habe. if (!ServerConfig.neighbours.Exists(x => x.ToString() == package.GetSource())) { //1. Anzahl Verbindungen (s. neighbours) if (package.anzConn == P2PPackage.AnzConnInit || package.anzConn > ServerConfig.neighbours.Count) { //Wenn das Paket noch nicht angefasst wurde, oder wir ein mind. genausogutes Angebot haben geht es als Antwort zurück. package.anzConn = ServerConfig.neighbours.Count; package.lastIP = ServerConfig.host.ToString(); } else if (package.anzConn == ServerConfig.neighbours.Count) { package.lastIP = ServerConfig.host.ToString(); } } //2. Test on TTL if (package.DecrementTTL() == 0) { package.P2PAnswer = P2PAnswer.Timeout; break; } //3. Forking to other servers via flooding returnList = Forward(); //Comparing answers foreach (P2PPackage p in returnList) { if (p.P2PAnswer == P2PAnswer.Error) { package.ErrorMsg = GenerateErrorString(); /*package.Exception = p.Exception;*/ } else if (package.anzConn >= p.anzConn) { package.anzConn = p.anzConn; package.lastIP = p.lastIP; } } break; case P2PRequest.RegisterServer: //1. Nimm Server in neighbours auf. (Falls noch nicht existent) if (!ServerConfig.neighbours.Exists(x => x.ToString() == package.GetSource())) { ServerConfig.neighbours.Add(IPAddress.Parse(package.GetSource())); package.P2PAnswer = P2PAnswer.Success; } else { package.P2PAnswer = P2PAnswer.Visited; } break; case P2PRequest.NewUser: //0. Existiert der User? if (ServerLogic.database.UserExist(package.GetUsername())) { package.P2PAnswer = P2PAnswer.UserExistent; break; } //1. Anzahl User int anzUser = ServerLogic.database.GetUserCount(); if (package.anzUser == P2PPackage.AnzUserInit || package.anzUser > anzUser) { // siehe case NewServer package.anzUser = anzUser; package.lastIP = ServerConfig.host.ToString(); } else if (package.anzUser == anzUser) { package.lastIP = ServerConfig.host.ToString(); } //2. Test on TTL ???? -> Nein! Nicht vereinbar mit nur einem User im gesamten Netz. /*if (package.DecrementTTL() == 0) * { * package.P2PAnswer = P2PAnswer.Timeout; * break; * }*/ //3. Forking to other servers via flooding returnList = Forward(); //Comparing answers foreach (P2PPackage p in returnList) { if (p.P2PAnswer == P2PAnswer.Error) { package.ErrorMsg = p.ErrorMsg; /*package.Exception = p.Exception;*/ package.P2PAnswer = P2PAnswer.Error; return(package); } else if (package.anzUser >= p.anzUser) { package.anzUser = p.anzUser; package.lastIP = p.lastIP; } } package.P2PAnswer = P2PAnswer.Success; break; /* * case P2PRequest.RegisterUser: * //Client should connect directly to register. * break; */ case P2PRequest.Login: //1. Check Datenbank nach user if (!ServerLogic.database.UserExist(package.GetUsername())) //2. Wenn nicht gefunden => weiterleiten { returnList = Forward(); //Falls nur ein return => Success if (returnList.Count == 1) { package.P2PAnswer = returnList.First().P2PAnswer; package.lastIP = returnList.First().lastIP; } else if (returnList.Count > 1) { foreach (P2PPackage p in returnList) { if (p.P2PAnswer == P2PAnswer.Success) { package.lastIP = p.lastIP; } } } else { package.P2PAnswer = P2PAnswer.Failure; //Error? } } else { package.lastIP = ServerConfig.host.ToString(); package.P2PAnswer = P2PAnswer.Success; } break; case P2PRequest.Invite: //1. Check Datenbank nach user if (!ServerLogic.database.UserExist(package.GetUsername())) //2. Wenn nicht gefunden => weiterleiten { returnList = Forward(); foreach (P2PPackage p in returnList) { if (p.P2PAnswer == P2PAnswer.Success) { package.P2PAnswer = p.P2PAnswer; package.lastIP = p.lastIP; } } } else { ServerLogic.database.SaveInvites(package.GetUsername(), package.GetInvite()); package.lastIP = ServerConfig.host.ToString(); package.P2PAnswer = P2PAnswer.Success; } break; default: break; } } catch (Exception ex) { Console.WriteLine(ex.Message); package.P2PAnswer = P2PAnswer.Error; package.ErrorMsg = GenerateErrorString(ex); /*package.Exception = ex;*/ //throw; } } else { package.P2PAnswer = P2PAnswer.Visited; //Node wurde bereits angefragt, keine Aktion nötig } return(package); List <P2PPackage> Forward() { Package sendPackage = new Package(package); Package recievePackage; List <P2PPackage> returnList = new List <P2PPackage>(); foreach (IPAddress iPAddress in ServerConfig.neighbours) { recievePackage = ServerLogic.Send(sendPackage, iPAddress); if (recievePackage != null) { if (recievePackage != null && recievePackage.p2p.P2PAnswer == P2PAnswer.Success) { return new List <P2PPackage>() { recievePackage.p2p } } ; returnList.Add(recievePackage.p2p); } } return(returnList); } }