WinFuture-Forum.de: Kleines Tcplistener Problem Bei C# - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Kleines Tcplistener Problem Bei C#


#1 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 11:06

Also ich bin gerade dabei n kleinen Chat zu prgrammieren und mich in die Materie einzuarbeiten.
Client und Server stehen soweit, nur beim Server hab ich noch so meine Probs.
public static void Main()
		{
			eServer e_server = new eServer();
		}
		public eServer()
		{
			TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"),13000);
			//Console.WriteLine("Waiting for Clients");
			server.Start();
			TcpClient client = server.AcceptTcpClient();
			Thread listen_to_client = new Thread(new ThreadStart(ListenToClient));
			listen_to_client.Start();
		}

das soweit der Sercer Code.
Man sieht sobald ein Client Connected wird dieser in einem neuen Thread ausgelagert.
Meine Frage nun: Wie "übergebe" ich auch den Clienten in den Thread sodass dieser weis mit wem er kommunizieren soll.
Da hapert es bei mir im Moment :/
mfg skelle
0

Anzeige



#2 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 11:13

Entweder du setzt den Client als ein Attribut der Klasse eServer oder du übergibst ihn als Parameter der Methode ListenToClient.
Ich bevorzuge jedoch die erste Variante.
0

#3 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 11:19

die 2. methode hatte ich auch schon probiert, die klappt aber irgendwie nicht :D
und könntest mir für die erste vllt n kl. Codebeispiel geben? verstehe nich ganz was du meinst, bin wie gesagt noch nich so vertraut mit der Materie :D
mfg skelle
0

#4 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 11:25

public class EServer
{
	 private TcpClient client = null;
	 public EServer()
	 {
		  ....
		  this.client = server.AcceptTcpClient();
	 }
}

0

#5 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 12:03

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using SharedComponent;
using System.Threading;

namespace Eigener_Server
{
	public class eServer
	{
		private TcpClient client = null;
		public static void Main()
		{
			while (true)
			{
				eServer e_server = new eServer();
			}
		}
		public eServer()
		{
			TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"),13000);
			//Console.WriteLine("Waiting for Clients");
			server.Start();
			this.client = server.AcceptTcpClient();
			Thread listen_to_client = new Thread(new ThreadStart(ListenToClient));
			listen_to_client.Start();
			server.Stop();
		}

	   void ListenToClient()
		{
			TcpClient tcp_client = this.client;
			 NetworkStream stream = tcp_client.GetStream();
			 BinaryReader r = new BinaryReader(stream);
			 BinaryWriter w = new BinaryWriter(stream);
			 if (r.ReadString() == ClientMessages.RequestConnect)
				{
					w.Write(ServerMessages.AcknowledgeOK);
					Console.WriteLine("Connection OK");
				}
			 if (r.ReadString() == "Name")
				{
					Console.WriteLine(r.ReadString() + " connected");
				}
			 Console.ReadLine();
		 }
  }
}


So danke erstma WITI soweit geht das Programm jetzt erstma soweit.
Ich hab ma den gesamten QT des Servers gepostet da ich jetzt noch weitergehende Fragen hab :D

1. Hab ich Programmiertechnisch alles richtig gemacht, sodass jede Verbindung ihren eigenen Thread hat? ja oder
2. Wie kann ich jetzt gucken wieviele, und welche Clients alle connected sind
3. und wie kann ich diese dann ansprechen?

Weil wenn Client 1 Text zum Server schickt soll dieser ja dann zu allen anderen Clients gesendet werden(vom Server aus)
mfg skelle

Dieser Beitrag wurde von skelle bearbeitet: 08. März 2006 - 12:03

0

#6 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 12:46

1. Nein, dein Server wird nach der ersten Verbindung ausgehen: Er wartet auf eine Verbindung, erstellt die Verbindung zum Client und nachdem die Daten abgearbeitet worden sind, schließt er die Verbindung. Kannst das z.b. mit einer while(true) Schleife lösen. (Jedoch würde ich das nicht im Konstruktor lösen, so wie du es jetzt hast)

2. s. 1. Zur Zeit kann sich nur ein Client verbinden :D

3. Was meinst du mit ansprechen? Du machst es schon richtig, indem du Nachrichten in den Stream schreibst. Diesen Stream liest der Client dann aus.

Dieser Beitrag wurde von Witi bearbeitet: 08. März 2006 - 12:47

0

#7 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 13:43

So zu 1/2:
Is das so in dem dreh richtig?
		public eServer()
		{
				TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
				//Console.WriteLine("Waiting for Clients");
				server.Start();
			while (true)
			{
				this.client = server.AcceptTcpClient();
				Thread listen_to_client = new Thread(new ThreadStart(ListenToClient));
				listen_to_client.Start();
			}

Und mit 3. meinte ich:
Ich muss doch irgendwie die Verbundenen Clients auch einzeln ansprechen könnnen oder?
Und deswegen eine Auflistung von allen Verbundenen Clients

Und ich hab noch was:
Mein Client is eine WindowsApplication.
Es gibt 2 Buttons:
Connect und Send

Connect geht -> er verbindet zum Server aber bei Send hab ich ein Problem
private void BSend_Click(object sender, EventArgs e)
		{
			TcpClient client = new TcpClient();
			NetworkStream stream = client.GetStream();
			BinaryReader r = new BinaryReader(stream);
			BinaryWriter w = new BinaryWriter(stream);
			w.Write("test");
			LText.Items.Add(r.ReadString());
		}

Das der Code des Buttons
Problem is folgendes:
Beim Ausführen sagt er dass: client.GetStream()
nich bei bereites verbundenen Objekten geht und wie bekomme ich jetz hin dass auch dieser Knopf den Stream vom Connectbutton mit benutzen kann?
mfg skelle
0

#8 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 14:15

1. Du musst "AcceptTcpClient" schon in den Thread auslagern, da _diese_ Methode so lange wartet, bis ein Client eine Anfrage startet.

2. Nicht alles in der Konstruktor. Im Konstruktor initialisiert man in der Regel nur seine Objekte und Variablen, die man benötigt. Lager alles nach inklusive server.Start() in eine Methode aus.

3. Für jeden Client, der sich verbindet musst du einen neuen Thread starten. Das ist quasi eine 1 zu n Beziehung (1 Servern n Clients). Dieses stellst du am besten mit einer Liste (bsp: ArrayList) dar. Wenn du in C# 2.0 programmierst, eignet sich eine Generische Liste hervorragend dafür.

Des Weiteren guck mal, ob dir dieser Link weiterhilft: http://www.microsoft.com/germany/msdn/libr...gMitCSharp.mspx
0

#9 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 15:27

 public static void Main()
		{
				eServer e_server = new eServer();
		}
		public eServer()
		{
				TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
				Console.WriteLine("Waiting for Clients");
				server.Start();
				while (true)
				{
					//this.client = server.AcceptTcpClient();
					Thread listen_to_client = new Thread(new ThreadStart(ListenToClient));
					listen_to_client.Start();
				}
		}
	   void ListenToClient()
		{

			 TcpClient tcp_client = this.server.AcceptTcpClient();
			 NetworkStream stream = tcp_client.GetStream();
			 BinaryReader r = new BinaryReader(stream);
			 BinaryWriter w = new BinaryWriter(stream);
			 if (r.ReadString() == ClientMessages.RequestConnect)
				{
					w.Write(ServerMessages.AcknowledgeOK);
					Console.WriteLine("Connection OK");
				}
			 if (r.ReadString() == "Name")
				{
					Console.WriteLine(r.ReadString() + " connected");
				}
				if (r.ReadString() == "test")
				{
					Console.WriteLine("test back");
				}
			 Console.ReadLine();
		 }
  }

So das Problem is nur dass this.server im thread immer "null" ist, warum weiss ich nich genau, aber auf jeden Fall gibbet immer ne Exception :/

Und zu der Sache mit der Methode:
Soll ich im prinzip einfach den Text von eServer ab der 3. Zeile in eine andere Methode tun und diese dann aufrufen?
0

#10 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 15:52

(Btw gewöhn dir mal an Klassennamen groß zu schreiben)
Logisch, im oben geposteten Code existiert auch kein Attribut server :8):
"private TcpListener server..."

Yep, zum Beispiel könnte es so aussehen (natürlich noch nicht fertig ;)):
Main:
public static void Main()
{
	 EServer server = new EServer("localhost", 1337);
	 server.Start();
}

Konstruktor:
public EServer(string host, int port)
{
	 IPAddress ip = Dns.Resolve(host).AddressList[0];
	 this.server = new TcpListener(ip, port);
}

Start:
public void Start()
{
	 this.server.Start();
	 Thread th = new Thread (new ThreadStart (this.ListenToClient));
	 th.Start ();
}

0

#11 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 08. März 2006 - 16:11

public class eServer
	{
		private TcpListener server;
		public static void Main()
		{
			eServer server = new eServer("localhost",13000);
			while (true)
			{
				server.Start();
			}
		}
		public eServer(string host, int port)
		{
				IPAddress ip = Dns.Resolve(host).AddressList[0];
				this.server = new TcpListener(ip, port);
				Console.WriteLine("Waiting for Clients");
		}
		public void Start ()
		{
			this.server.Start();
			Thread listen_to_client = new Thread(new ThreadStart (this.ListenToClient));
			listen_to_client.Start();
		}

	   void ListenToClient()
		{

			 TcpClient tcp_client = server.AcceptTcpClient();
			 NetworkStream stream = tcp_client.GetStream();
			 BinaryReader r = new BinaryReader(stream);
			 BinaryWriter w = new BinaryWriter(stream);
			 if (r.ReadString() == ClientMessages.RequestConnect)
				{
					w.Write(ServerMessages.AcknowledgeOK);
					Console.WriteLine("Connection OK");
				}
			 if (r.ReadString() == "Name")
				{
					Console.WriteLine(r.ReadString() + " connected");
				}
			 if (r.ReadString() == "test")
				{
					Console.WriteLine("test back");
				}
			 Console.ReadLine();
		 }
  }


Soweit ok, hab das Programm nach deinen Vorschlägen umgeschrieben und geht auch soweit.
Wenn ich jetzt jedoch mit dem Clienten ein 2. Mal etwas an den Server sende is es auch schonwieder vorbei, und als Fehler bekomme ich dasss der Remotehost die Verbindung beendet hat.
Und nochwas: Was macht dieses "this" eigentlich genau? Es wird ja anscheinend sehr häufig verwendet aber ich hab noch nich ganz verstanden was es macht. :8): Hab auch schon im VS nachgeguckt aber da staht zum GRoteil nur wo man es häufig verwendet.
mfg skelle
0

#12 Mitglied ist offline   stefanra 

  • Gruppe: aktive Mitglieder
  • Beiträge: 6.208
  • Beigetreten: 13. September 04
  • Reputation: 1

geschrieben 08. März 2006 - 16:12

this ist relativ auf die aktuelle Instanz, es spart dir eine Menge Tipparbeit.
0

#13 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 08. März 2006 - 22:39

Beitrag anzeigenZitat (stefanra: 08.03.2006, 16:12)

this ist relativ auf die aktuelle Instanz, es spart dir eine Menge Tipparbeit.

Mit einer IDE nur ein t und tab ;)

Ich persönlich setze this eigentlich immer ein, wegen der besseren Übersicht.

skelle...hast du dir eigentlich den Link, den ich ein paar Posts drüber gepostet habe wenigstens mal angeguckt?
Das ist nämlich genau das was du brauchst!
0

#14 Mitglied ist offline   skelle 

  • Gruppe: aktive Mitglieder
  • Beiträge: 793
  • Beigetreten: 15. Juli 04
  • Reputation: 0

geschrieben 09. März 2006 - 16:55

Witi ich hab mir die Seite schon durchgelesen aber zu dem Problem im CLient mit dem Stream hab ich da nix gefunden :8):
Ich hab ja 2 Buttons und frag mich jetz im Prinzip wo ich den BinaryReader und -Writer starte dass ich sie im gesamten Formular zur Verfügung hab.
mfg skelle
0

#15 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 10. März 2006 - 11:30

Wenn du ein Objekt in einer ganzen Klassen zur Verfügung haben möchtest, eignet sich bspw das Objekt als Attribut der Klasse zu deklarieren.
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0