Entwickler-Ecke
WinForms - Label aktualisieren funktioniert nicht
MiHa80 - Fr 24.10.08 12:30
Titel: Label aktualisieren funktioniert nicht
Hallo,
ich schaffe es nicht, das der Text "verbunden" angezeigt wird, sobald sich der Server verbunden hat.
Wie kann ich das Label ereignisfenster von der KLasse ServerThread verändern ?
Desweiteren möchte ich noch die IP-Adresse von den verbundenen Clients ausgeben. Wie kann ich diese IP-Adressen herausfinden ?
Könnt ihr mir helfen ?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151:
| namespace Backup_Test
{ public partial class MainForm : Form { private static TcpListener tcpListener; private static ArrayList threads = new ArrayList(); private static int maxConnections = 100;
public MainForm() { InitializeComponent(); }
void MainFormLoad(object sender, EventArgs e) { ServerStarten(); }
public delegate void SetTextCallback(string text); public void SetText(string text) { if (this.ereignisfenster.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.ereignisfenster.Text = (ereignisfenster.Text + text); } }
public void ServerStarten() { tcpListener = new TcpListener(IPAddress.Any, 9050); tcpListener.Start(); Thread mainThread = new Thread(new ThreadStart(Run)); mainThread.Start(); this.ereignisfenster.Text = (ereignisfenster.Text + "Backup-Server"); this.ereignisfenster.Text = (ereignisfenster.Text + "\nWarte auf Verbindungen...");
}
public void Run() { while (true) { if (threads.Count < maxConnections) { TcpClient c = tcpListener.AcceptTcpClient(); this.SetText("\nVerbindungsanfrage erkannt\n"); threads.Add(new ServerThread(c)); } } }
class ServerThread { public static int uebergabe; public bool stop = false; public bool running = false; private TcpClient connection = null; private NetworkStream networkStream; private byte[] data = new byte[1024]; private int received; private string empfangen;
public ServerThread(TcpClient connection) { this.connection = connection; new Thread(new ThreadStart(Run)).Start(); }
public void Run() {
this.running = true; networkStream = connection.GetStream(); bool loop = true;
data = "Willkommen auf Backup-Server".ToByteArray(); networkStream.Write(data, 0, data.Length);
while (loop) { try { Listen(); loop = !this.stop; } catch (Exception) { loop = false; } } networkStream.Close(); this.connection.Close(); this.running = false; }
public void Listen() { var arrOK = "Client1".ToByteArray(); var arrNOK = "Client2".ToByteArray(); while (true) { data = new byte[1024]; received = networkStream.Read(data, 0, data.Length); if (received == 0) break;
empfangen = Encoding.ASCII.GetString(data, 0, 2); switch (empfangen) { case "10": networkStream.Write(arrOK, 0, arrOK.Length); break; case "20": networkStream.Write(arrNOK, 0, arrOK.Length); break; } } } } |
Moderiert von
Christian S.: Highlight- durch C#-Tags ersetzt
bakachan - Fr 24.10.08 13:05
Hallo,
ich habe mir den Quellcode jetzt nicht so wirklich angesehn(Hinweis: es gibt Code-Tags oder auch C#-Code-Tags hier im Forum damit wird der Quellcode besser lesbar).
die sauberere Variante:
Events
Mach dir ein paar Events in deiner Klasse und koppel die in deiner Oberfläche.
An den Stellen wo der Text verändert werden soll löst du das entsprechende Event aus sodass deine Oberfläche weiss wann sie den Text zu ändern hat.
die unschöne Variante:
Referenz des Objekts mit in die Funktionen übergeben.
jaenicke - Fr 24.10.08 13:05
Hallo und :welcome: hier!
So wie du den Quelltext gepostet hast ist der leider unlesbar. Erstens fehlt jede Einrückung, so dass man schon keinen Überblick hat, und dann hast du noch Highlight-Tags statt C#-Tags verwendet, so dass das den Quelltext gänzlich unlesbar macht.
Manchmal habe ich den Eindruck, dass sich niemand den abgeschickten Beitrag noch einmal durchliest, das musst du doch selbst merken, dass der Quelltext so nicht überschaubar ist. :roll:
MiHa80 - Fr 24.10.08 13:11
Sorry,
hab die C# Tags nicht gefunden. Werde es beim nächsten mal beachten.
Das mit den Events funktioniert leider nicht, wohl wegen der Klasse ServerTHread, die ja was übergeben haben will. Deshalb bekam ich beim Compilieren immer Fheler als ich das mit Events versucht habe.
Vielleicht kann mir hier jemand einen Vorschlag machen, wie das anhand dieses Quellcodes mit Events funktioniert.
Wie funktioniert das mit der Referenz des Objektes mit in die Funktion übergeben ?
Danke für eure Hilfe.
bakachan - Fr 24.10.08 15:17
Das mit Events sollte eigentlich funktionieren (zumindest wenn ich nicht grad irgend nen Leichtsinnsfehler mache, was Freitag Nachmittag durchaus möglich wäre):
Erstelle in deiner ServerThread-Klasse ein/mehrere Event/-s
z.B.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| class ServerThread { public event EventHandler TestEvent; . . . } |
An der entsprechenden Stelle (also da wo sich bei dir z.B. der Status ändern sollte) rufst du das Event auf:
C#-Quelltext
1:
| TestEvent(this,new EventArgs()); |
Damit das ganze nicht ins leere läuft musst du aber von deiner Oberflächen-Form aus noch abonieren(oder koppeln oder wie auch immer man es nennen will).
z.B.:
C#-Quelltext
1: 2: 3: 4:
| this.SetText("\nVerbindungsanfrage erkannt\n"); ServerThread server = new ServerThread(c); server.TextEvent += new EventHandler(Funktion); threads.Add(server); |
und dazu noch die Funktion an die du es aboniert hast(in die Formklasse):
C#-Quelltext
1: 2: 3: 4:
| private void Funktion(object sender, EventArgs e) { } |
Kha - Fr 24.10.08 15:21
MiHa80 hat folgendes geschrieben : |
| Das mit den Events funktioniert leider nicht, [...] |
Doch ;) . Gib deiner ServerThread-Klasse ein neues Event vom Typ SetTextCallback, rufe es in ServerThread.Run auf und verknüpfe es in MainForm.Run:
C#-Quelltext
1: 2: 3: 4: 5:
| TcpClient c = tcpListener.AcceptTcpClient(); this.SetText("\nVerbindungsanfrage erkannt\n"); var thread = new ServerThread(c); thread.Log += SetText; threads.Add(thread); |
PS: InvokeRequired finde ich persönlich schrecklich, ich mache es immer so (.Net 3.5):
C#-Quelltext
1: 2: 3:
| thread.Log += message => Invoke(new Action(() => { ereignisFenster.Text += message; })); |
PS: bakachan war zwar schneller :evil: , aber ich lasse es mal stehen, vielleicht hilft's.
MiHa80 - Fr 24.10.08 16:08
Super,
ihr seid die Besten.
Hat auf Anhieb funktioniert und ich weiß wieder ein wenig mehr.
Übrigens, das ist ein super Forum hier.
Wisst ihr evtl. auch noch wie man die IP-Adresse der verbundenen Clients auslesen kann ?
MiHa80 - Fr 24.10.08 19:44
gerade ist mir noch aufgefallen, wenn ich das Fenster mit dem X beende, läuft immer noch das Programm weiter. Der Debugger bei SharpDevelop läuft dann nämlich immer noch.
Hab auch schon mit dem OnClose Event die Application.Exit eingefügt, bringt aber auch nichts
Kha - Sa 25.10.08 00:16
Setze IsBackground deiner Thread auf true. Warum, das verrät dir die Hilfe ;) . Bei weitergehenden Fragen über die ursprüngliche Frage hinaus solltest du aber der Übersichtlichkeit zuliebe lieber einen neuen Thread aufmachen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!