Laden...

Forenbeiträge von darkangel1208 Ingesamt 20 Beiträge

17.03.2019 - 09:30 Uhr

Und noch als Hinweis:

Ich würde mich nie auf den Text als Auswahlkriterium verlassen - zum einen kannst du nicht lokalisieren und zum anderen reicht eine kleine ANpassung des Textes, dass deine ABfrage im Sande verläuft. Nimm für soetwas entweder das Attribute "Tag" oder leite von Button ab und füge eine eigenes Attribute ein.

Tja was soll ich dazu sagen Stefan. Ich habe hier keinen Text als Auswahlkriterium. Das sind Datenbankenabfragen und oder Sensordaten. Aber sie könnten so, oder ähnlich aussehen, wenn man sie in klarschrift als Text sehen könnte. Damit das ganze nicht zu wust wird, habe ich alles unwichtige rausgenommen und zu deinem Link da oben. den kenn ich schon. Das habe ich mir die letzen 2 Tage durchgelesen. HILFT aber NICHT weiter in meinem Fall. Weil es auf der empfängerform nichts gibt, wo ich z.B. einen Eventhandler anheften könnte.

17.03.2019 - 05:55 Uhr

ja, das wurde schon 1000 mal besprochen und ich habe es an andere stelle schon mit einem eventhandler hinbekommen. Nur diesmal habe ich kein wirkliches Event dazu.

Ich habe eine Hauptform (Form 1) und 16 weitere Forms (2-17).
In meiner Hauptform habe ich einen Network Server Socket gestartet mit ip-Adresse und port laso TCP/IP kommunikation. Das funktioniert. die 16 anderen Forms repräsentieren 16 physikalische Blackboxes mit sensoren in einem Netzwerk. Die Sensoren senden auf anfrage ihre Daten.

Mein Problem.... wenn ich jetzt vom Sensor die daten per mouseclick haben will. Dann ist der Button in Form2(-17) und muss diese Anfrage an die Hauptform weitergeben, damit die Hauptform die Anfage per TCP losschickt. oder ich muss den erstellten TCP Socket aus Form1 an Form2(-17) weitergeben, damit ich die methoden nutzen kann und Form2(-17) direkt die anfrage per TCP losschickt.

Welche Variante ist schlauer?

Letztere habe ich nicht hinbekommen und erstere scheitert zur Zeit daran, dass ich zwar in Form2(-17)die Daten Richtung Form1 übergeben kann, aber in Form1 gibt es zur Zeit keine Stelle im Code, wo ich die Daten in empfang nehmen könnte. Dort bräuchte ich sowas wie eine loop und wie ich die jetzt hinbekomme, bin ich grad zu blöd für. ich meine nicht while(true) oder so. Diese loop darf ja auch nicht den rest blockieren. Da fallen mir dann Threats ein. Nennt mir ein paar schlagworte, wie ihr das angehen würdet.


class Data
    {
        private static string Daten;
        public static string getDaten()
        {
            return Daten;
        }
        public static void setDaten(string value)
        {
            Daten = value;
        }
    }

Form2


        private void btn_start_stop_Click(object sender, EventArgs e)
        {
            if (btn_start_stop.Text == "Start")
            {
                btn_start_stop.Text = "Stop";
                senden(Reaktornummer + "#2#70#80#90");
            }
            else
            {
                btn_start_stop.Text = "Start";
                senden(Reaktornummer + "#2#0#0#0");
            }
        }
        private void senden(string Daten)
        {
            Data.setDaten(Daten);
        }

Form1


// hier fehlt die loop für diesen methodenaufruf
        private string empfangen(string Daten)
        {
            return Datenstrom = Data.getDaten();
        }

10.12.2016 - 01:28 Uhr

Problem 1:
Hmm soweit klappt das zwar jetzt. Aber alles was in meinem gestartetem Task läuft kann ja wiederrum nicht auf Textboxen der GUI zugreifen.
Wenn ich es mit this.invoke versuche, klappt das leider auch nicht.
Problem 2:
Dadurch das senden und empfangen jetzt in eigenen tasks laufen kann ich das gesendete RGBh mit dem empfangenen RGBz nicht mehr vergleichen, weil zu dem zeitpunkt, wenn ich RGBz empfange, die daten in RGBh schon evtl. wieder überschrieben wurden. (nicht immer aber manchmal)


       private void bnMouseClick_Click(object sender, EventArgs e)
        {
            Task bbcSenden = new Task(new Action(BlackBodyCurve));
            bbcSenden.Start();
        }

        private void BlackBodyCurve()
        {
            uhr.Start();
            // erst wenn die schleife komplett durchgelaufen ist und bnMouseClick_Click verlassen wurde
            // springt der Code in Empfangen rein und verarbeitet die angekommenen Daten und nicht schon sobald
            // die Daten ankommen
            for (int i = 1; i < 1175; i++)
            {
                txtReceive.AppendText("\r\n"); //Fehler
                RGBh = (bbc[i, 9] + "#" + bbc[i, 10] + "#" + bbc[i, 11]);
                TimeSpan zeit = uhr.Elapsed;
                double zeitneu = zeit.TotalMilliseconds;
                if ((zeitneu - zeitalt) >= 80) // erst senden, wenn 80 millisekunden seit dem letzten senden vergangen sind
                {
                      Senden(); // Senden an IO Port
                }
                else
                {
                      i=i-1;
                }
            }
            txtReceive.AppendText("\r\n ende"); // Fehler
            uhr.Stop();

        }

        private void Senden()
        {
            try
            {
                if (RGBh.Length > 0)
                {

                    Arduino.Write(RGBh); //senden an den IO Port
                   // txtReceive.AppendText("\r\n <<<<: " + rgb[0] + "  #  " + rgb[1] + "  #  " + rgb[2]);
                    ScollToBottom();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK);
            }
        }

        private void Empfangen(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                RGBz = Arduino.ReadLine(); // empfangen vom IO port
                Berechnung_rgb_xy(); // Daten verarbeiten und in picturebox1 anzeigen
                this.Invoke(new EventHandler(Empfangen_event));
            }
            catch
            {
                MessageBox.Show("Error Serial Event Handler, cannot listen for data", "Error", MessageBoxButtons.OK);
            }
        }

        private void Empfangen_event(object sender, EventArgs e)
        {
            txtReceive.AppendText("\r\n xyz back :" + xyz[0] + "  #  " + xyz[1] + "  #  " + xyz[2]);
            txtReceive.AppendText("\r\n----------------------------------------------------------------------------------------------");
            }
            ScollToBottom();
        }

@Abt: ich verstehe was du meinst und ja bräuchte man eigentlich nicht, aber wie löse ich jetzt mein Problen nr. 2?

08.12.2016 - 21:09 Uhr

Ich weiß nicht genau ob ich hier wirklich 2 Threads brauche.
Zum besseren Verständnis... ich weiß nicht wirklich wie lange die jetzt dafür brauchen....

Form1 sendet Daten über den IO-Port an ein Gerät
Dort werden die Daten verarbeitet und dann zurückgesendet.
Bei empfang von Daten des IO-Ports in der Form1, werden die Daten ausgewertet und in einer Picturebox angezeigt, bzw. in eine Textbox geschrieben

Angenommen ich sende an den IO-Port Daten und zwar 1175 mal. Das ganze würde z.B. 20 sekunden dauern.
Das externe Gerät empfängt die Daten und sendet schon nach erhalt des ersten Datensatz, also nach 3 sekunden zurück.
Aber auf der Gui wird erst nach 20 sekunden etwas in die picturebox, bzw. textbox geschrieben. Sprich 17 sekunden lang haben die Daten darauf gewartet, bis die Gui mit dem senden fertig war und sich um die empfangen Daten kümmern kann.

Problem kurz:
Form1 -> senden Daten 1
Form1 -> senden Daten 2
// etc.
Form1 -> senden Daten 1175
Form1 <- empfangene Daten1 verarbeiten
Form1 <- empfangene Daten2 verarbeiten
//etc.
Form1 <- empfangene Daten1175 verarbeiten

ich hätte aber gerne, das das senden ünterbrochen wird, sobald daten ankommen und sich darum gekümmert wird. Also eine höhere Priorität haben. Am besten so...
(Geht das nur mit threads? oder gibt es da eine kurz elegante Lösung. Denn Threads habe ich mir schon durchgelesen, aber finde ich doch schwer zu begreifen wie ich das auf mein Problem anwenden könnte.)

Form1 -> senden Daten 1
Form1 <- empfangene Daten1 verarbeiten
Form1 -> senden Daten 2
Form1 <- empfangene Daten2 verarbeiten
Form1 -> senden Daten 3
Form1 <- empfangene Daten3 verarbeiten
// etc.
Form1 -> senden Daten 1175
Form1 <- empfangene Daten1175 verarbeiten


        private void bnMouseClick_Click(object sender, EventArgs e)
        {
            uhr.Start();
            // erst wenn die schleife komplett durchgelaufen ist und bnMouseClick_Click verlassen wurde 
            // springt der Code in Empfangen rein und verarbeitet die angekommenen Daten und nicht schon sobald 
            // die Daten ankommen
            for (int i = 1; i < 1175; i++)
            {
                txtReceive.AppendText("\r\n");
                RGB = (bbc[i, 9] + "#" + bbc[i, 10] + "#" + bbc[i, 11]);
                TimeSpan zeit = uhr.Elapsed;
                double zeitneu = zeit.TotalMilliseconds;
                if ((zeitneu - zeitalt) >= 80) // erst senden, wenn 80 millisekunden seit dem letzten senden vergangen sind
                {
                      Senden(); // Senden an IO Port
                }
                else
                {
                      i=i-1;
                }
            }
            txtReceive.AppendText("\r\n ende");
            uhr.Stop();
            
        }

        private void Senden()
        {
            try
            {
                if (RGB.Length > 0)
                {

                    Arduino.Write(RGB); //senden an den IO Port
                    txtReceive.AppendText("\r\n <<<<: " + rgb[0] + "  #  " + rgb[1] + "  #  " + rgb[2]);
                    ScollToBottom();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK);
            }
        }

        private void Empfangen(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                RGB = Arduino.ReadLine(); // empfangen vom IO port
                Berechnung_rgb_xy(); // Daten verarbeiten und in picturebox1 anzeigen
                this.Invoke(new EventHandler(Empfangen_event));
            }
            catch
            {
                MessageBox.Show("Error Serial Event Handler, cannot listen for data", "Error", MessageBoxButtons.OK);
            }
        }

        private void Empfangen_event(object sender, EventArgs e)
        {
            txtReceive.AppendText("\r\n xyz back :" + xyz[0] + "  #  " + xyz[1] + "  #  " + xyz[2]);
            txtReceive.AppendText("\r\n----------------------------------------------------------------------------------------------");
            }
            ScollToBottom();
        }

08.12.2016 - 19:56 Uhr

Verwende bei gleichen Klassen in verschiedenen Dateien

 partial class Verbindung  

und wichtig den gleiche Namespace...

Jo danke du hast mich auf den richtigen Weg gebracht.


// Form1.cs
namespace Lichtmischung
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            /****/
        }
        /******/
    }
}



// Verbindung.cs
namespace Lichtmischung
{
    partial class Form1
    {
        private void bnConnect_Click(object sender, EventArgs e)
        {
            if (OpenPortConnection())
            {
                txtInput.Enabled = Boolean.Parse("True");
                bnConnect.Enabled = Boolean.Parse("False");
                bnDisconnect.Enabled = Boolean.Parse("True");
                cbPorts.Enabled = Boolean.Parse("False");
                txtReceive.Text += "\r\n Port Activated";
                ScollToBottom();
            }
        }
    }
}

Manchmal ist das Problem dann doch ganz einfach. Wenn man weiß wonach man googln muss. Aber so Sachen wie 'C# quellcode auslagern' bringt einen zu Seiten, wo erklärt wird, wie man Methoden oder abgekapselte Klassen schreibt. Auf das "partial" bin ich nicht gekommen.
Aber wenn man das im Prinzip nie braucht und dann plötzlich nach Jahren mal wieder was Programmieren soll.... und das letzte mal als man vor jahren Code auslagerte das noch in Cpp / Konsolenanwendung war. Ja dann sieht man den Wald vor Bäumen nicht.
Jetzt klappt das alles so, wie ich das wollte.

08.12.2016 - 11:51 Uhr

Hi,

Mein programmcode funktioniert soweit, aber ich bin damit noch nicht fertig und es sind jetzt schon über 500 Zeilen.

Die Gui verbindet sich über den USB-port zu einem gerät und schickt dem dann Daten und empfängt auch wieder. Das senden von Daten hin und zurück passiert sehr oft, aber wenn alles richtig lief, wird die Verbindung zum Gerät nur einmal hergestellt und wenn das Programm geschlossen wird, wieder getrennt.

Ich würde gerne den Programmcode, der für das Herstellen der Verbindung und Trennen dieser zuständig ist in eine eigene Datei auslagern. Geht das? denn dieser Code reagiert ja auf Buttonclicks oder schreibt in Textfelder oder nutzt globale Variablen.

Wenn ich eine neue .cs Datei erstelle, meckert der Code das er ja das alles nicht kennt. Hmmm verstehe ich ja auch irgendwie. Es soll ja auch mehr so sein das der Code ausgelagert ist und bei Laufzeit an entsprechender Stelle eingefügt wird in der Form1.cs. So als hätte er schon imemr da gestanden und nie in der Ausgelagerten Datei.

Hier ein Beispielcodesnipsel den ich gerne auslagern möchte.


//Verbindung.cs
namespace Lichtmischung
{
    class Verbindung
    {
        public static bool OpenPortConnection()
        {
            bool successFlag = true;
 // Arduino ist der System.IO.Ports.SerialPort.Name
 // cbPorts ist die Combocox in der Gui
            try
            {
                if (Arduino.IsOpen) Arduino.Close(); //if the port is already open, close it
                Arduino.PortName = cbPorts.SelectedItem.ToString(); //Get Port Name and set it.
                Arduino.Open(); //Open Port.
            }
            catch
            {
                MessageBox.Show("Erroring Port. Please check if a Port was selected.", "ERROR", MessageBoxButtons.OK);
                successFlag = false;
            }
            return successFlag;
        }
    }
}

Die Hautdatei, wo dieser Codeschnipsel mal drinstand und auch einwandfrei funktionierte


// Form1.cs
private void bnConnect_Click(object sender, EventArgs e)
        {
         // if (OpenPortConnection())
            if (Verbindung.OpenPortConnection())
            {
                txtInput.Enabled = Boolean.Parse("True");
                bnConnect.Enabled = Boolean.Parse("False");
                bnDisconnect.Enabled = Boolean.Parse("True");
                cbPorts.Enabled = Boolean.Parse("False");
                txtReceive.Text += "\r\n Port Activated";
                ScollToBottom();
            }
        }

Aber ich bekomme natürlich Fehler das er die IO ports und comboboxen nicht kennt.

Fehlermeldung:
Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler CS0103 Der Name "Arduino" ist im aktuellen Kontext nicht vorhanden. Lichtmischung D:\EigeneProjekte\Lichtmischung2\Lichtmischung\Verbindung.cs 23 Aktiv

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler CS0103 Der Name "cbPorts" ist im aktuellen Kontext nicht vorhanden. Lichtmischung D:\EigeneProjekte\Lichtmischung2\Lichtmischung\Verbindung.cs 24 Aktiv

31.03.2010 - 20:31 Uhr

ah super ja ich ka nicht drauf

hatte

this.location = (MousePosition.X, MousePosition.Y)

da gab natürlich nur Fehlermeldungen. Super nun funktioniert alls klasse

31.03.2010 - 16:27 Uhr

Hmm komm nun doch net mehr weiter.
Ich hab mir nun den code zusammen gebastelt, das ne Messagbox kommt solbald die form das Fensterverlässt. läuft auch alles richtig so, dochich will die Zeile mit der Messagebox nun ersetzten durch, dass es sich nicht weiterschieben lassen osll. Da stehe ich aber uf dem Schlauch. Neu Zeichnen ist zwar toll, aber die Location property ist schreibgeschützt.


        private void Mahjongg_LocationChanged(object sender, MouseEventArgs e)
        {
            if (((this.Location.X + this.Size.Width) >= breite) || (this.Location.X < 0) || ((this.Location.Y + this.Size.Height + 30) >= höhe) || (this.Location.Y < 0))
            {
                ausserhalb = true;
                MessageBox.Show("Stop");
            }
            else
                ausserhalb = false;
        }

Denn da meine form keine Titelleiste mehr hat und dort ein toolStrip liegt , lasse ich mit dem folgendem code bei gedrückerter Moustaste das Fenster verschieben. aber wie kombiniere ich die beiden? denn auf ausserhalb == false reagiert er erst, wenn ich die muose einmal loslasse und wieder drücke.


        private void Mahjongg_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if ((e.Button == MouseButtons.Left) && (ausserhalb == false))
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

31.03.2010 - 15:04 Uhr

Wow sovieleAntworten, werd mich gleich mal dranbegeben
Danke 👍 👍

31.03.2010 - 13:26 Uhr

Hmm ich finde dazu leider nix im Netz, hab auch keine Ahnung was ich bei Google noch eingeben könnte.

Man kann die Form (nach dem Ausführen) oben an der blauen Leiste anfassen und verschieben. Ich möchte nun, dass man die Form zwar verschieben kann aber nicht über den Rand des Desktops hinaus. Also die Form soll nicht halb rechts aus dem Monitor geschoben werden können. (links, oben, unten genauso)

Gibts dafür nen Befehl oder so? Kann wer helfen?

12.02.2010 - 21:56 Uhr

bin wieder am verzweifweln. die clientNr habe ich beim ersten verbinden übergeben. das läuft wunderbar. Doch wenn ich nun daten senden will, geht er beim server bis an die stelle "Handling client at 8" dann kommt die meldung in einem extrafenster: "Auf das verworfende Objekt kann nicht zugegriffen werden. objektname: System.Net.Sockets.Socket." dann so 1-2 sekunden später geht er noch bis nach "Handling client at 10". Dann läuft die sanduhr und im Fensterrahmen steht oben keine rückmeldung. Aber ich bin vollkommen verwirrt.

ich habe die vermutung das es mit den zeilen . . . zutunhat

              CSock.Shutdown(SocketShutdown.Both);
               CSock.Close();

Doch sicher bin ich nicht.
Da ich den Server nicht debuggen kann, habe ich überall diese "Handling client at [zahl]" drinne, damit ich sehe wo er zuletzt stehen geblieben ist.
das goto mit einer sprungmarke schlechter Programmierstil ist, weiß ich, aber wenn ich eine Endlose schleife dahin baue, hängt sich er Server sofort auf, sobald ich auf start klicke.

ich habe den client


        private void senden_Click(object sender, EventArgs e)
        {
            byte[] byteBuffer = Encoding.ASCII.GetBytes(Inhaltschicken.Text);

            string IP = IPAdresse.Text;
            int Port = Convert.ToInt32(PortNr.Text);

            // Instanziere einen Endpunkt mit der IP-Adresse
            IPEndPoint IP_Endpunkt = new IPEndPoint(IPAddress.Parse(IP), Port);
            // Initialisiere Socket - IPv4,Stream,TCP
            CSock = new Socket(IP_Endpunkt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            // Öffne eine Socket Verbindung
            CSock.Connect(IP_Endpunkt);
            if (CSock.Connected)
            {
                MessageBox.Show("Connected to " + IPAdresse.Text, "MessageBox",
                                   MessageBoxButtons.OK, MessageBoxIcon.Information);

                // Sende den enkodierten string an den server
                CSock.Send(byteBuffer, 0, byteBuffer.Length, SocketFlags.None);

                Inhaltschicken.Text=("Sent bytes to server..."+ byteBuffer.Length);
                /*  int totalBytesRcvd = 0;
                  int bytesRcvd = 0;

                  // Empfange denselben string wieder vom server
                  while (totalBytesRcvd < byteBuffer.Length)
                  {
                      if ((bytesRcvd = CSock.Receive(byteBuffer, totalBytesRcvd,
                                                   byteBuffer.Length - totalBytesRcvd,
                                                   SocketFlags.None)) == 0)
                      {
                          Inhaltschicken.Text = ("Connection closed preaturely.");
                          break;
                      }
                      totalBytesRcvd += bytesRcvd;
                  }

                  Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd,
                                    Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));*/

                CSock.Shutdown(SocketShutdown.Both);
                CSock.Close();
            }
        }

und den server


        private const int BACKLOG = 11;
        private const int BUFSIZE = 32;
        int TeilnehmerNr = 0, i = 0;
        bool merker = false;
        string[] TeilnehmerIP = new string[11];
        Socket CSock = null;

        private void start_Click(object sender, EventArgs e)
        {
            Inhaltschicken.Text = ("Handling client at 1");
            try // gehe ins diesen Zweig. Sobald ein Fehler auftritt, gehe nach catch, ansonten nie
            {
                
                //start.Enabled = false;
                int Port = Convert.ToInt32(PortNr.Text);
                Inhaltschicken.Text = ("Handling client at 2");
                Socket SSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Inhaltschicken.Text = ("Handling client at 3");
                // Assoziiert den Socket mit einem lokalen Endpunkt
                SSock.Bind(new IPEndPoint(IPAddress.Any, Port));
                Inhaltschicken.Text = ("Handling client at 4");
                // Versetzt den Socket in den aktiven Abhörmodus für maxiaml 11 Teilnehmer
            TOP:
                Inhaltschicken.Text = ("Handling client at 5a");
                SSock.Listen(BACKLOG);
                Inhaltschicken.Text = ("Handling client at 5b");


                // Wartenden Client annehmen
                CSock = SSock.Accept();
                Inhaltschicken.Text = ("Handling client at 6");
                // ClientIP rausfiltern
                string[] ClientNr = CSock.RemoteEndPoint.ToString().Split(':');
                Inhaltschicken.Text = ("Handling client at " + ClientNr[0]);

                merker = false;
                Inhaltschicken.Text = ("Handling client at 8");
                // Rausfiltern, ob der Client Daten senden darf.
                for (i = 0; i < 11; i++)
                {
                    // Client schon in der Liste
                    if (ClientNr[0] == TeilnehmerIP[i])
                    {
                        merker = true;
                        DatenEmpfangen(ClientNr[0]);
                        Inhaltschicken.Text = ("Handling client at 9");
                    }
                }
                Inhaltschicken.Text = ("Handling client at 10");
                // Client nicht in der Liste
                if (merker == false)
                {
                    Inhaltschicken.Text = ("Handling client at 11");
                    // Teilnehmerliste noch nicht voll
                    if (TeilnehmerNr < 11)
                    {
                        TeilnehmerIP[TeilnehmerNr] = ClientNr[0];
                        TeilnehmerNr++;
                        Inhaltschicken.Text = ("Handling client at 12");
                    }
                    // Client schließen, weil keine Berechtigung
                    else
                    {
                        Inhaltschicken.Text = ("Client schließen, weil keine Berechtigung");
                    }
                }
                CSock.Shutdown(SocketShutdown.Both);
                CSock.Close();
            goto TOP;
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }
07.02.2010 - 09:58 Uhr

Doch noch ne Frage. ^^'

Ich habe mich nun entschieden, kein Multicast zu verwenden, da mir die Überprüfung, ob datenpakete angekommen sind, wichtig ist und ich somit TCP brauche.

  1. Wenn ich nun mit einem Server und 11 Clienten arbeite, kann es ja pasierern, dass der Server gerade Datenpakete rausschickt und gleichzeitig der Client etwas zum Server schickt, aber der ist ja beschäftigt.
    Um dort aufkommende Problem zu vermeiden, sollte ich dann das Ganze ins Threads verwalten oder ist das unnötig?

  2. Wenn ein Client etwas zum Server schikt, was dann an alle anderen Clienten geschikt werden soll mit der Info von welchem Clienten es kam, brauche ich doch die IP des Clienten von dem es ursprünglich kam, oder?
    Wie ich die IP nicht ermitteln? Weil dazu finde ich nix passendes.

06.02.2010 - 20:53 Uhr

Auf der von mir oben verlinkten Seite steht nichts falsches und es ist dort eigentlich auch verständlich erklärt. So meinte ich das nicht, ich lese ja nicht nur auf deiner Seite, sondern auch auf anderen, wenn ich dann mal nen hänger habe und es dort einfach net verstehe grad oder mir unsicher bin.

Das Zeitdruck nie gut ist, ist mir klar. Aber das das ganze Projekt den Bach runtergeht nur weil einer dann keinen Bock mehr hat, weils ihm zu viel ist sich einzulesen ist doof und dann muss man das noch übernehmen, neben der eigentlichen Aufgabe. Wir haben ne Deadline und bis dahin muss es irgendwie laufen, das ist grad erstma wichtig und danach kann man es noch verbesern bis zu dem Termin wo die Abgabe der dazugehörigen Doku mit dem Programm auf CD ist.

Dann werde ich mal basteln und hoffen es klappt dann wie ich denke.

06.02.2010 - 20:23 Uhr

ja aber übers Internet soll es ja auch nicht gehen, nur über netzwerk. Ok nun gibt es ja nun keinen Server mehr sonder nur Clienten.

  1. Aber kann man denn nun noch überhaupt sicherstellen irgendwie, das das Paket auch bei allen angekommen ist, da das UPD nicht überprüft (wie TCP)

  2. Für die Limitierung, dass nur 11 Clienten es maximal empfnagen dürfen und zwar nur die, die am selben "Pokertisch" sitzen. Dafür bräuchte ich wieder Multicast, oder.

Ich les auch an vielen Stellen, aber ich habe das Gefühl das auf vielen Seiten auch was falsches steht oder schlecht erklärt. Ich würde nicht hier fragen, wenn ich jemand anderen wüsste, der es mir bestätigen könnte oder nciht, was ich mir zusammenlese und daraus entnehme, aber ich stehe leider etwas unter Zeitdruck und kann nicht erst auf zu vielen irrwegen wandeln, denn eigentlich sollte dieser Part der Arbeit wer anderes machen, aber der hat schlichtweg keinen Bock.
Von daher danke ich für die nachsicht. =)

06.02.2010 - 14:51 Uhr

ok nochwas, was ich nicht verstehe.

Jetzt ist dort zwar auf seite 4 beschrieben wie man über UDP sendet und empfängt, aber ich frage mich, gibts denn immernoch sowas wie einen Server und Clienten und ist das mehr so wie in einen Torrentnetzwerk wie bei dem Esel wo es ja nur noch mitglieder gibt die jenachdem Client und gleichzeitig Server sind.

Desweiteren frage ich mich, wenn noch niemand im Broadcast drinne ist, müsste der erste es ja eröffnen oder? Irgendwie steh ich auf der Leitung.

06.02.2010 - 11:43 Uhr

Mal ne kurze Frage zwischendurch, ob ich das richtig verstanden habe.

Da ich ja nur maximal 11 Clienten und 1 Server im Netzwerk habe könnte ich das Ganze über Broadcast versenden. Aber über Multicast scheint es einfacher zu realisieren zu sein in C#.

Frage 1: Wenn ich Broadcast/Multicast nutze, geht das nur über UDP oder auch über TCP?

Frage 2: Muss ich die Verbindung die zwischen Client und Server besteht nach jeden übertragen von Daten wieder schließen und neu öffnen wenn es wieder was zu übertragen gibt, oder kann die Verbindung bestehen bleiben auch wenn beide mal 2,3 Minuten nicht kommunizieren. Oder kommt dann nach einer bestimmten Zeit sowas wie ne Zwangstrennung, weil keiner was sagt.

05.02.2010 - 09:27 Uhr

ok. Netzwerk ist auch nicht meine Stärke.

Ich taste mich erstmal langsam ran. Nun habe ich mir den Code vom Echo-Server genommen und dort nur einen festen Port angegeben.

Wenn ich nun die Konsole öffne und dort dann die Server.exe aufrufe kommt folgende Fehlermeldung mit der ich nicht weiterkomme.

10047: Es wurde eine Adresse verwendet, die mit dem angeforderten Protokoll nich
t kompatibel ist


using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;

namespace Server
{
    /// <summary>
    /// Ein synchroner TCP-Server, der alle empfangenen Daten
    /// wieder umgehend an den Clienten zurück sendet.
    /// </summary>
    public class Server
    {
        public static void Main(string[] args)
        {
            if (args.Length > 1)
            {
                throw new ArgumentException("Parameters: [<Port>]");
            }

            int servPort = 4700;

            Socket servSock = null;

            try
            {
                // Verwende explizit IPv6
                servSock = new Socket(AddressFamily.InterNetworkV6,
                                      SocketType.Stream,
                                      ProtocolType.Tcp);

                // Assoziiert den Socket mit einem lokalen Endpunkt
                servSock.Bind(new IPEndPoint(IPAddress.IPv6Any, servPort));

                // Versetzt den Socket in den aktiven Abhörmodus 
                servSock.Listen(BACKLOG);
            }
            catch (SocketException se)
            {
                Console.WriteLine(se.ErrorCode + ": " + se.Message);
                Environment.Exit(se.ErrorCode);
            }

            byte[] rcvBuffer = new byte[BUFSIZE];
            int bytesRcvd;

            // Lässt den Server in einer Endlosschleife laufen
            for (; ; )
            {
                Socket client = null;

                try
                {
                    client = servSock.Accept();

                    Console.Write("Handling client at " + client.RemoteEndPoint + " - ");

                    // Empfange bis der client die Verbindung schließt, das geschieht indem 0
                    // zurückgegeben wird
                    int totalbytesEchoed = 0;
                    while ((bytesRcvd = client.Receive(rcvBuffer, 0, rcvBuffer.Length,
                                                       SocketFlags.None)) > 0)
                    {
                        client.Send(rcvBuffer, 0, bytesRcvd, SocketFlags.None);
                        totalbytesEchoed += bytesRcvd;
                    }
                    Console.WriteLine("echoed {0} bytes.", totalbytesEchoed);

                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    client.Close();
                }
            }
        }

        private const int BUFSIZE = 32;
        private const int BACKLOG = 5;
    }
}

Für die Clientseite habe ich folgendes mir zusammengesucht und muss dann doch nur noch wenn beides läuft, einen Stream vom Client zum Server schicken und dort wird er ausgegeben und dann zurückgeachickt und am Client wieder ausgegeben


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Client
{
    class Client
    {
        static void Main(string[] args)
        {
            try
            {
                //Socket sock = null;
                const int Port = 4700;
                const string IP = "172.0.0.1";

                // Instanziere einen Endpunkt mit der IP-Adresse
                IPAddress ipo = IPAddress.Parse(IP);
                IPEndPoint ipEo = new IPEndPoint(ipo, Port);

                // IPv4 oder IPv6, Stream Socket, TCP
                Socket sock = new Socket(ipEo.AddressFamily,
                                  SocketType.Stream,
                                  ProtocolType.Tcp);

                // Öffne eine Socket Verbindung
                sock.Connect(ipEo);

                // Prüfe ob eine Verbindung besteht?
                if (sock.Connected)
                {
                    Console.WriteLine(" - Connection established!\n");
                    // Socket schließen und Ressourcen freigeben
                    sock.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}
04.02.2010 - 22:47 Uhr

das ist es ja eine Fehlermeldung kommt nicht. Einfach nur keine Rückmeldung vom Programm mehr und das wars.

z.B. Kapiere ich nicht wozu ich eine Echo-Server brauche. ich will die Daten ja nicht wiederbekommen, die ich an den Server geschickt habe die sollen an alle anderen Clienten geschickt werden.

Fast der kompletten ersten beiden Seiten der Code dort, wenn der ausgeführt wird, geht eine konsolenfenster auf und sofort wieder zu, bevor ich etwas sehen kann.

Der kram mit HTTP ist nicht nötig soweit ich weiß, da ich ja nur im Netzwerk agiere und keinen Internetanschluss brauche und auch niemals darauf zugreifen will.

Eine IP-Adresse muss ich auch nicht auflösen aus einer Domaine, da ich diese kenne, genauso wie den Port und alle anderen wichtigen Adressen, da wir die einfach festgelegt hat und somit nicht erst wegen der Dynamic ermitttelt werden müssen.

Und ab Seite 3 schlackern mir dann die Ohren und ich klomme nicht mehr hinterher. Aber auch das Durchlesen der 2 Seiten davor macht mich nicht schlauer für seite 3

Ich kann mir auch nicht vorstellen ,das alle 7 Seiten wichtig sind, einfach nur einen String von PC a nach PC b zu schicken und das der Server irgendwann, wenn man es ihm sagt einen Sieger ermittelt ( geht um ien Pokerspiel über Netzwerk)

04.02.2010 - 20:54 Uhr

ja genau den Link hatte ich schon und habe mir das 2 Tage lang unter anderem durchgelesen aber ich bin nur verwirrt.

Vorallem wenn ich einem 2. client auf dem selben Rechenr starte, fängt alles an zu spinnen und schmirt ab und ich schnall nicht, ob das so gewollt ist oder nicht. Denn ich habe ja mehr als nur 1 Client.

04.02.2010 - 19:12 Uhr

Nachdem ich viel gelesen habe, bin ich aber irgendwie noch genausoschlau wie am Anfang.
Das Ganze mit Win Sockets hat mich nur verwirrt .

Wenn ich eine Win Form mit einem Butoon habe und ich diesen Button drücke, möchte ich einen String an mehrer andere Rechner schicken und dort in der Form in einem Label ausgeben.

Wie gehe ich das Ganze am besten an, denn zueiander verbinden müssen die sich ja auch noch im Netzwerk.