Laden...

Netzwerk Bibliothek

Erstellt von Sweet vor 15 Jahren Letzter Beitrag vor 14 Jahren 13.062 Views
S
Sweet Themenstarter:in
119 Beiträge seit 2008
vor 15 Jahren
Netzwerk Bibliothek

Beschreibung:

Da die anderen Netzwerk Biblitheken die ich im Internet fand nie ganz meinen Bedüfnissen entsprachen hab ich mal meine eigene geschrieben sie besitzt alle wichtigen Events und ein paar nützlich Zusatzfunktionen.

Man kann damit so ziemlich alles sehr einfach programmieren. Peer to Peer Anwendungen sind ebenso möglich wie Client Server Anwendung, der Programmier Aufwand ist ein Minimum.

Sollte irgendwer Bugs finden oder allgemein Verbesserungsvorschläge haben bitte gleich hier posten 🙂

Schlagwörter: Netzwerk Bibliothek Chat Datei Senden

Hier erstmal eine einfache Beispiel Anwendung samt DLL

"2 Dinge sind unendlich die Dummheit der Menschen und das Universum, aber beim Universum bin ich mir noch nicht so ganz sicher."

  • Albert Einstein
3.971 Beiträge seit 2006
vor 15 Jahren

Hallo sweet,
verkaufe deine Bibliothek doch bitte noch was besser. Zeig ein paar Beispiele, wie man deine Bibliothek verwenden, welche konkreten Vorteilen denn davon genau hat. Wenn es eine Bibliothek ist, wäre eine kurze Doku zu einzelnen Funktionen auch nicht schlecht.

habe grad gesehen, der Quellcode zu dieser Bibliothek liegt nicht vor, ist das gewollt?

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

S
Sweet Themenstarter:in
119 Beiträge seit 2008
vor 15 Jahren

Das ist jetzt der Source der neuesten Version der Klasse in der ich ein paar Bugs ausgebessert habe

"2 Dinge sind unendlich die Dummheit der Menschen und das Universum, aber beim Universum bin ich mir noch nicht so ganz sicher."

  • Albert Einstein
S
Sweet Themenstarter:in
119 Beiträge seit 2008
vor 15 Jahren

Verwendung der Klasse:

Grundsätzliches

Um eine einfache Peer to Peer Anwendung zu erstellen braucht man nicht sehr viel Code:

public partial class Form1 : Form
    {
        AdvancedNetSend _Net = null;
        public Form1()
        {
            InitializeComponent();

            //Hier finden wir erst mal unsere lokale Ip heraus.
            IPAddress IP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

            //Hier wird eine neue Instanz der AdvancedNetSend Klasse instanziert
            _Net = new AdvancedNetSend(IP, 28030);
            
            //Und hier werden die ganzen Events registriert. Ich glaube der Name der
            //Events sagt alles über sie aus :-)
            _Net.NewClient += new AdvancedNetSend.ClientEventHandler(_Net_NewClient);
            _Net.ClientDisconnect += new AdvancedNetSend.ClientEventHandler(_Net_ClientDisconnect);
            _Net.MessageRecieved += new AdvancedNetSend.MessageRecievedEventHandler(_Net_MessageRecieved);
            _Net.FileRecieved += new AdvancedNetSend.FileReceivedEventHandler(_Net_FileRecieved);            
        
            //Hier connecten wir dann zu uns selbst
            _Net.Connect(IP, 28030);

            //Dannach senden wir hier eine einfach Nachricht
            _Net.SendMessage("Test Nachricht 123");

            //Hier wählen wir mitels eines OpenFileDialogs ein File zum Senden aus
            OpenFileDialog _file = new OpenFileDialog();
            if (_file.ShowDialog() == DialogResult.OK)
            {
                //Und hier wird es letztendlich gesendet
                _Net.SendFile(_file.FileName);
            }
        }

        void _Net_FileRecieved(FileRecievedEventArgs e)
        {    
            //Hier zeigen wir eine MessageBox um den Benutzer auf das Empfangen eines
            //Files aufmerksam zu machen. Die EventArgs enhalten alle Informationen
            //Das File als Byte Array. Die IP des Senders und den Datei Namen.
            //Außerdem eine Methode um das File gleich irgendwo zu speichern
            MessageBox.Show("Sie haben das File " + e.FileName + " von dem Clienten " + e.IP + " erhalten");
            
            //Hier wählt der Benutzer mit dem SaveFileDialog erst mal den Speicherort
            //aus
            SaveFileDialog _save = new SaveFileDialog();
            _save.FileName = e.FileName;
            if (_save.ShowDialog() == DialogResult.OK)
            {
                //Und hier wird das File dann mit der SaveFile Methode von den EventArgs
                //gespeichert
                e.SaveFile(_save.FileName);
            }
        }

        void _Net_MessageRecieved(MessageRecievedEventArgs e)
        {
            //Wenn wir eine neue Nachricht erhalten wird sie über eine MessageBox 
            //ausgegeben. Die EventArgs enthalten wieder die IP des Senders
            //und die Nachricht an sich
            MessageBox.Show("Neue Nachricht vom Clienten " + e.IP + ":\n\n" + e.Message);
        }

        void _Net_ClientDisconnect(ClientEventArgs e)
        {
            //Dazu gibts nicht viel zu sagen. Die EventArgs enhalten nur die IP des 
            //Senders
            MessageBox.Show("Der Client " + e.IP + " ist disconnectet");
        }

        void _Net_NewClient(ClientEventArgs e)
        {
            //Dieses Event kann aus programmier technischen Gründen nicht 
            //getriggert werden wenn man zu sich selbst connectet
            //Die EventArgs enhalten nur die IP des Senders
            MessageBox.Show("Ein neuer Client mit der IP " + e.IP + " hat zu ihnen connectet");
        } 
    }

** Sonstiges **

Von jeder Send Methode gibt es immer 2 Version z.B.:


//Sendet eine Nachricht an alle verbundenen Clients
public void SendMessage(string Text)

//Sendet eine Nachricht an eine bestimmte IP. Funktioniert nur wenn zu der IP schon connectet wurde
public void SendMessageTo(string Text, IPAdress IP)

So ist das auch bei SendFile oder SendByte

** Zusätzliche Methoden und Funktionen **

Die Klasse arbeitet beim Senden und Empfangen immer nach dem gleichen Schema. Egal ob man ein File oder eine Nachricht oder sonst was sendet, es wird immer mit der folgenden Methode ein Byte Array erstellt:

public Byte[] GeneratePackage(int Type, int IntegerContent, string StringContent, Byte[] ByteContent)

Dieses Byte Array wird dann versendet. Der Empfänger unterscheidet dann durch den Integer Type was er empfangen hat:

0 = Nur zum Testen. Es werden alle Zeilen Code durchlaufen aber kein Event getriggert
1 = Neue Text Nachricht
2 = Datei empfangen

Sollte Type einen anderen Wert haben wird das UnknownPackageRecieved Event getriggert. Bei den EventArgs diese Events stehen wieder der Integer Type der Integer IntegerContent der string StringContent und das Byte Array ByteContent von der GeneratePackage Methode zur Verfügung.

Hier ein Beispiel dazu:

public partial class Form1 : Form
    {      
        public Form1()
        {
            InitializeComponent();
            //Hier holt man sich zuerst die lokale IP
            IPAddress IP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

            //Dannach instanziert man hier eine neue Instanz der AdvancedNetSend Klasse
            AdvancedNetSend _Net = new AdvancedNetSend(IP, 28030);

            //Hier connecten wir dann zu uns selbst
            _Net.Connect(IPAddress.Parse(IP), 28030);

            //Und erstellen hier mit der GeneratePackage Methode ein Byte Array
            //Der Typ ist 4 der Integer Content ist 40, und der String Content "Test"
            Byte[] _ToSend = _Net.GeneratePackage(4, 40, "Test", null);  
         
            //Hier versenden wir das Byte Array dann noch
            _Net.SendBytes(_ToSend);

            //Zum Schluss registrieren wir dann noch das UnknownPackageRecieved Event
            _Net.UnknownPackageRecieved += new AdvancedNetSend.UnknownPackageEventHandler(_Net_UnknownPackageRecieved);
        } 
        void _Net_UnknownPackageRecieved(UnknownPackageEventArgs e)
        {
            //Hier überprüfen wir ob die erhaltenen Daten wirklich unserer oben 
            //erstellten Beispiel Nachricht entsprechen
            if (e.Typ == 4) 
            { 
                //Wenn das zutrifft wird hier beides ausgegeben
                MessageBox.Show(e.StringContent + "\n" + e.IntContent); 
            }
        }
    }

Das hab ich eingebaut damit der Benutzer die Möglichkeit hat die Klasse einfach seinen eigenen Bedürfnissen anzupassen.

** Hooks **

Hooks sind eine Spezielle Möglichkeit um z.B. /-Kommandos in einem Chat Programm zu vereinfachen. Hier eine Übersicht der Methoden:


//Registriert einen neuen Hook
public void AddHook(object _Hook, MethodInvoker _Void)

//Entfernt einen Hook
public void RemoveHook(object _Hook)

//Überprüft ob ein Hook existiert
public bool HookExists(object _Hook)

//Führt einen Hook aus
public void HookInvoker(object _Hook)

Hier eine kleine Beispiel Anwendung:

public partial class Form1 : Form
    {
        AdvancedNetSend _Net = null;
        public Form1()
        {
            InitializeComponent();

            //Hier finden wir erst mal unsere lokale Ip heraus.
            IPAddress IP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

            //Hier wird eine neue Instanz der AdvancedNetSend Klasse instanziert
            _Net = new AdvancedNetSend(IP, 28030); 

            //Hier registrieren wir das HookExecuted Event das wird jedes mal getriggert
            //wenn ein Hook ausgeführt wird
            _Net.HookExecuted += new AdvancedNetSend.HookExecutedEventHandler(_Net_HookExecuted);

            //Hier registrieren wir einen neuen Hook
            _Net.AddHook("/Test", new MethodInvoker(Test));
        }
        void _Net_HookExecuted(HookEventArgs e)
        {
            //Hier weisen wir den Benutzer darauf hin das ein Hook ausgeführt wurde,
            //zeigen ihm an welcher und geben ihm die Möglichkeit ihn abzubrechen
            if (MessageBox.Show("Ein Hook wurde ausgeführt:\n\nName: " + e.ExecutedHook + "\nTarget: " + e._VoidToExecute.Method.Name + "\n\nWollen sie den Hook abbrechen?", "Hook ausgeführt", MessageBoxButtons.YesNo) == DialogResult.Yes)
            { 
               //Wenn der Benutzer auf Yes klickt wird die Ausführunf unterbrochen
                e.Cancel = true;
            }
        }
        private void Test()
        {
            MessageBox.Show("Test Kommando ausgeführt");
        }
        private void btnSend_Click(object sender, EventArgs e)
        {
            //Mit diesem Button wird der Text aus der RichTextBox rtxtMessage
            //versendet
            string _Message = rtxtMessage.Text;

            //Wir gehen davon aus das das Kommando als erstes steht
            string _Command = _Message.Split()[0].Trim();

            //Jetzt überprüfen wir ob das erste Wort wirklich ein Kommando ist
            if (_Net.HookExists(_Command))
            {
                //Wenn das erste Wort ein registriertes Kommando ist wird es 
                //ausgeführt
                _Net.HookInvoker(_Command);
            }
            else
            {
                //Andernfalls die Nachricht gesendet
                _Net.SendMessage(_Message);
            }
        } 
    }

Liste alle Methoden und Events und Eigenschaften und Delegates

** Methoden **


    /// <summary>
    /// Fügt einen Hook hinzu
    /// </summary>
    /// <param name="_Hook">Das Object das den Hook auslösen soll</param>
    /// <param name="_VoidToStart">Der Void der gestartet werden soll</param>
    public void AddHook(object _Hook, MethodInvoker _VoidToStart)

    /// <summary>
    /// Entfernt einen Hook
    /// </summary>
    /// <param name="_Hook"></param>
    public void RemoveHook(object _Hook)

    /// <summary>
    /// Überprüft ob ein Hook existiert
    /// </summary>
    /// <param name="_Hook">Der zu überprüfende Hook</param>
    /// <returns></returns>
    public bool HookExists(object _Hook)

    /// <summary>
    /// Löst Hooks aus
    /// </summary>
    /// <param name="_Hook">Der Hook der ausgelöst werden soll</param>
    public void HookInvoker(object _Hook)

    /// <summary>
    /// Connectet zu einem anderem Computer
    /// </summary>
    /// <param name="IP">Die Ip zu der Connectet werden soll</param>
    /// <param name="Port">Der Port zu dem Connectet werden soll</param>
    public void Connect(IPAddress IP, int Port)

    /// <summary>
    /// Sendet eine Nachricht an alle verbundenen Computer
    /// </summary>
    /// <param name="Text">Die zu sendende Nachricht</param>
    public void SendMessage(string Text)

    /// <summary>
    /// Sendet eine Nachricht an einen bestimmten Computer. Funktioniert nur bei verbundenen Clients
    /// </summary>
    /// <param name="Text">Die zu sendende Nachricht</param>
    /// <param name="IP">Die IP Adresse des Ziel Computers</param>
    public void SendMessageTo(string Text, IPAddress IP)

    /// <summary>
    /// Pingt einen anderen Computer an
    /// </summary>
    /// <param name="IP">Die IP Adresse des zu pingenden Computers</param>
    /// <returns>Die Latenz in Milli Sekunden</returns>
    public int Ping(string IP)

    /// <summary>
    /// Überprüft ob ein andere Computer online ist
    /// </summary>
    /// <param name="IP">Die IP Adresse des zu überprüfenden Computers</param>
    /// <returns>Ob der Computer online ist</returns>
    public bool IsOnline(string IP)

    /// <summary>
    /// Sendet ein File an alle verbunden Computers
    /// </summary>
    /// <param name="Path">Der Pfad des zu sendenden Files</param>
    public void SendFile(string Path)

    /// <summary>
    /// Sendet ein File an einen bestimmten Computer. Funktioniert nur bei verbundenen Clients
    /// </summary>
    /// <param name="Path">Der Pfad des zu sendenden Files</param>
    /// <param name="IP">Die IP Adresse des Ziel Computers</param>
    public void SendFileTo(string Path, IPAddress IP)

    /// <summary>
    /// Sendet ein Byte Array an alle verbunden Clienten
    /// </summary>
    /// <param name="Buffer">Das zu sendende Byte Array</param>
    public void SendBytes(Byte[] Buffer)

    /// <summary>
    /// Sendet ein Byte Array an einen bestimmten Computer. Funktioniert nur bei verbundenen Clients
    /// </summary>
    /// <param name="Buffer">Das zu sendende Byte Array</param>
    /// <param name="IP">Die IP Adresse des Ziel Computers</param>
    public void SendBytesTo(Byte[] Buffer, IPAddress IP)

    /// <summary>
    /// Erstellt ein neues Byte Array das von der AdvancedNetSend Klasse entschlüsselt
    /// werden kann
    /// </summary>
    /// <param name="Type">Der Typ des Arrays zur Unterscheidung. 0 = Test Typ. 
    /// 1 = Text Nachricht. 2 = File. Alle anderen lösen das UnknownPackageRecieved
    /// Event aus.</param>
    /// <param name="IntegerContent">Eine zu sendende Integer Zahl</param>
    /// <param name="StringContent">Ein zu sender String</param>
    /// <param name="ByteContent">Ein zu sendes Byte Array</param>
    /// <returns>Das fertige Byte Array</returns>
    public Byte[] GeneratePackage(int Type, int IntegerContent, string StringContent, Byte[] ByteContent)

** Eigenschaften **


    /// <summary>
    /// Überprüft ob der aktuelle Computer eine Internet Verbindung besitzt
    /// </summary>
    public bool HasActiveInternetConnection

    /// <summary>
    /// Die externe IP Adresse des Computers
    /// </summary>
    public IPAddress WanIP

    /// <summary>
    /// Die lokale IP Adresses des Computers
    /// </summary>
    public IPAddress[] LocalIP

** Delegates **


    public delegate void FileReceivedEventHandler(FileRecievedEventArgs e);
    public delegate void MessageRecievedEventHandler(MessageRecievedEventArgs e);
    public delegate void ClientEventHandler(ClientEventArgs e);
    public delegate void UnknownPackageEventHandler(UnknownPackageEventArgs e);
    public delegate void HookExecutedEventHandler(HookEventArgs e);
   

** Events **


    /// <summary>
    /// Wird getriggert wenn ein neuer Client Connectet
    /// </summary>
    public event ClientEventHandler NewClient;

    /// <summary>
    /// Wird getriggert wenn ein Client Disconnectet
    /// </summary>
    public event ClientEventHandler ClientDisconnect;

    /// <summary>
    /// Wird getriggert wenn ein Versuch zu Connecten fehlschlägt
    /// </summary>
    public event ClientEventHandler ConnectingFailed;

    /// <summary>
    /// Wird getriggert wenn eine Neue Text Nachricht eintrifft
    /// </summary>
    public event MessageRecievedEventHandler MessageRecieved;

    /// <summary>
    /// Wird getriggert wenn eine neue Datei empfangen wurde
    /// </summary>
    public event FileReceivedEventHandler FileRecieved;

    /// <summary>
    /// Wird getriggert wenn ein Byte Array von unbekannten Typ empfagen wurde
    /// </summary>
    public event UnknownPackageEventHandler UnknownPackageRecieved;

    /// <summary>
    /// Wird getriggert wenn ein Hook ausgeführt wird
    /// </summary>
    public event HookExecutedEventHandler HookExecuted;

"2 Dinge sind unendlich die Dummheit der Menschen und das Universum, aber beim Universum bin ich mir noch nicht so ganz sicher."

  • Albert Einstein
3.430 Beiträge seit 2007
vor 15 Jahren

Hi,

da haste ein tolle Arbeit geleistet 👍, ich werde das bestimmt mal ausprobieren.

Ich habe da mal schnell den Code überfolgen und dabei ist mir eine Kleinigkeit aufgefallen.

In der Methode SendFile() habe ich da einen Fehler gefunden, und noch eine kleine "Unschönheit".

Da du ja im ersten Beitrag geschrieben hast, dass wir dich auf Bugs hinweisen sollen, poste ich meinen Tipp mal hier:


            if ( Path[Path.Length - 1] == Convert.ToChar("/") )
            {
                //Das hier bringt nix, da du den neuen String keiner Variable zuweist
                Path.Remove(Path.Length - 1);
                //Deshalb wäre es so zu ersetzen
                Path = Path.Remove(Path.Length - 1);
            }
            //Das hier würde ich auch nicht so machen, denn es mach wenig Sinn immer durch den ganzen Array durchzulaufen
            //Deshalb würde ich da einfach immer auf das letzte Element des Arrays zugreifen
            foreach ( string s in Path.Split(Convert.ToChar("/")) ) { FileName = s; }
            //Das ist vielleicht auch nicht die performateste Lösung, ich würde das aber so machen
            FileName = Path.Split('/')[Path.Split('/').Length - 1];

mfg
michlG

343 Beiträge seit 2007
vor 15 Jahren
  
            //Das ist vielleicht auch nicht die performateste Lösung, ich würde das aber so machen  
            FileName = Path.Split('/')[Path.Split('/').Length - 1];  
  

Es würde auch performant gehen mit den Funktionen string.Substring und string.LastIndexOf

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
S
Sweet Themenstarter:in
119 Beiträge seit 2008
vor 15 Jahren

Ok danke das ihr mich drauf aufmerksam gemacht hab 🙂

Ich hab jetzt grad keine Zeit aber ich werds bald ausbessern dann die neue Version uploaden

"2 Dinge sind unendlich die Dummheit der Menschen und das Universum, aber beim Universum bin ich mir noch nicht so ganz sicher."

  • Albert Einstein
S
Sweet Themenstarter:in
119 Beiträge seit 2008
vor 15 Jahren

Ok ich hab alles ausgebessert 😉

Die Downloads von den alten Versionen oben hab ich durch Downloads von der neuen Version ersetzt. Sowohl beim Beispiel als auch beim Source sind die Fehler ausgebessert

"2 Dinge sind unendlich die Dummheit der Menschen und das Universum, aber beim Universum bin ich mir noch nicht so ganz sicher."

  • Albert Einstein
F
10.010 Beiträge seit 2004
vor 15 Jahren

Noch einfacher wäre es, wenn Du mal System.IO.Path für die Pfadmanipulationen benutzen würdest.

N
8 Beiträge seit 2009
vor 14 Jahren
Problem bei der Verwenung

Hallo,

erstma ein Lob für die Klasse echt super zu verwenden, allerdings habe ich ein Problem bei der Verwenung.
Ich habe die Klasse in ein Datenbankprogramm von mir implementiert. Dort mach ich einen Server auf habe die Eventhandler für Client Con/Discon und Message Recived.

Weiter habe ich nun eine Konsolenanwendung erstellt die nichts anderes als das hier macht.


public static void Main(string[] args)
{
          AdvancedNetSend _Net = null; 
          IPAddress ownIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
          _Net = new AdvancedNetSend(ownIP, 28031);
          string a = args[0];
           _Net.Connect(ownIP, 28030);
          _Net.SendMessage(a);
}

Genutzt wird das damit ich über die Konsole einen Suchstring an die Datenbankanwendung schicken kann. Funktioniert auch aber nur einmal...
Führe ich eine zweite Anfrage aus stürzt meine Datenbankanwendung ab, eine Idee warum?

2.298 Beiträge seit 2010
vor 14 Jahren

Hallo, ich weiss, das Projekt und der Beitrag sind schon älter. Ich wollte nun aber keinen weiteren Thread deshalb eröffnen.

Ich habe es geschafft, eine Verbindung herzustellen mit meiner Serveranwendung.

Der Client konnte Nachrichten an diese schicken und sie worden dort direkt ausgegeben. Nun wollte ich aber X-Clients verbinden lassen und den Server selbst auch mit sich wie im Beispiel connecten lassen. - Auch dies klappt Problemlos.

Wird das Event OnMessageRecieved ausgelöst, wollte ich über die Serveranwendung die Nachrichten an alle verbundene Clients weiterleiten.

Überlegt hatte ich mir das wie folgt:


void _net_MessageRecieved(MessageRecievedEventArgs e)
		{
			if (e.Message.Contains("\\chat"))
			{
				if (lasmessage != e.Message)
				{
					_net.SendMessage(e.Message);					
					this.chatControl1.GotChat(e.Message.Substring(0, e.Message.Length - 5));
					lasmessage = e.Message;
				}
			}
		}

Doch hier tut sich garnichts und es kommt somit bei keinem Client etwas an.

Danach hab ich getestet, ob auf das Event OnNewClient reagiert wird. - Dies ist aber leider nicht der Fall. - Sonst hät ich dort versucht eine weitere Verbindung mit dem Client aufzubauen.

Hat jemand Erfahrung mit der Bibliothek, und könnte mir eventuell einen Tipp geben, wie ich das ganze realisieren kann, dass die Nachrichten an alle Clients weitergeleitet werden?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |