Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Server handelt mit mehrere Clients gleichzeitig auf einem Port
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

Server handelt mit mehrere Clients gleichzeitig auf einem Port

beantworten | zitieren | melden

Hi,
wie ist es in .NET möglich, das ein TCP Server (TcpListener) auf Port z.B. 1400 läuscht und mit sagen wir mal 10 Clients gleichzeitig arbeiten kann. So das sich also 10 Clients gleichzeitig mit dem Server verbinden können.

Habe das damals in C mit der Funktion select getan. Nur die konnte ich nicht im .NET finden. Zudem möchte ich eigentlich keine Sockets nutzen, sondern den Network Stream zur Datenverarbeitung nutzen. Ist das möglich oder muss man beim Server auf einen Socket zurückgreifen? Ich hab zwar eine Möglichkeit mit Asyncsockets gefunden, doch wie gesagt, ich würde lieber ohne Sockets arbeiten. Wie realisiert ihr das?
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4318
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Ja das geht problemlos

mit TCPListener und TcpClient
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

Ja aber wie geht das mit einem TCPListener das sich mehrere Clients gleichzeitig auf dem selben Port mit dem Server verbinden. Wie z.B. ein FTP Server. Dort können sich ja auch so und so viele Clients gleichzeitig drauf verbinden.
Vielleicht mal nen kleines code Stückchen oder nen Howto oder sonstiges.
private Nachricht | Beiträge des Benutzers
DecaTec
myCSharp.de - Member

Avatar #avatar-3493.png


Dabei seit:
Beiträge: 212

beantworten | zitieren | melden

Also im Grunde funktioniert das so, dass der TcpListener an einem bestimmten Port initialisiert wird. Auf diesem Port horcht der dann, ob Clients connecten wollen. Wenn dies der Fall ist, wird mit AcceptTcpClient() ein TcpClient-Object zurückgeliefert (das Accept... kann man im einfachsten Fall dann in einer Endlosschleife laufen lassen). Den TcpClient kannst du dann z.B. in einen Netzwerkstream verpacken.
Also das wichtigste in einem Satz: Die Clients bauen die Verbindung nicht mit dem TcpListener direkt auf, sondern jeder Client bekommt "seine eigene Conection".

Ausführliches Beispiel: MSDN
Blog

Portable WebDAV Library

Windows Server Advanced Power Management
Erweitertes Energie-Management unter Windows
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Jeder TCPListener im eigenen Thread....
private Nachricht | Beiträge des Benutzers
Fabian
myCSharp.de - Member

Avatar #avatar-1590.jpg


Dabei seit:
Beiträge: 1994
Herkunft: Dortmund

beantworten | zitieren | melden

Hallo,

jetzt noch eine Frage, weil ich neu in dem Gebiet bin und mich das interessiert: Wo liegt der Vorteil in der oben von exec beschriebenen Methode? Warum keine Verbindung über Sockets?
Was von beiden ist besser oder anders gefragt: Wann bevorzuge ich welche Methode?


Danke und Gruß,
Fabian
"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Der TCPClient arbeitet nur synchron, während die Sockets auch asychrone Funktionen haben.

Darüberhinaus sind Sockets schneller. Der TCPClient hat dafür nette Features wie Timeout-Handling.

Unter dem TCPClient liegen Sockets..... der TCPClient stellt sowas wie ein High-Level-Interface für TCP dar, Sockets sind low-level.

Ist also Mächtigkeit/Performance (Sockets) gegen Komfort (TCPClient).
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

@svenson wenn ich jeden tcplistener in einen eigenen thread verpasse.. dann hab ich ja für jeden client einen eigenen port. was ja ziemlcih doof ist. will ja nur ein port aber viele clients.
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

@exec: Hab das jetzt mal versucht. aber so kann ja auch nur maximal ein Client sich verbinden. Erst wenn sich der Client trennt, wartet der server auf einen neuen client der sich wieder verbindet.


public TcpListener tl;
		public NetworkStream ns;
		public StreamWriter sw;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.TextBox status_text;
		public StreamReader sr;

	
		//static int anzahl_clients = 10;

		

		public main_form()
		{
			//
			// Erforderlich für die Windows Form-Designerunterstützung
			//
			InitializeComponent();
			tl = new TcpListener(1400);
			tl.Start();

			while(true)
			{
				TcpClient tc = tl.AcceptTcpClient();
				ns = tc.GetStream();
				sw = new StreamWriter(ns);
				sr = new StreamReader(ns);
				sw.WriteLine("du bist verbunden");
				sw.Flush();
			}
			
			
			//
			// TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu
			//
		}

ich möchte aber das sich mehere Clients gleichzeitig mit dem Server binden auf dem selben Port.
private Nachricht | Beiträge des Benutzers
DecaTec
myCSharp.de - Member

Avatar #avatar-3493.png


Dabei seit:
Beiträge: 212

beantworten | zitieren | melden

Mit dem Port hat das ganr nichts zu tun. Auf dem Port "klopfen" die Clients nur am TcpListener an. Die daraufhin aufgebaute Verbindung hat mit dem Port nichts mehr zu tun (alle gehen über den gleichen Port).
Zum Codebeispiel: Jede Clientbehandlung im eigenen Thread.
Blog

Portable WebDAV Library

Windows Server Advanced Power Management
Erweitertes Energie-Management unter Windows
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

also sollte ich


	while(true)
			{
				TcpClient tc = tl.AcceptTcpClient();
				ns = tc.GetStream();
				sw = new StreamWriter(ns);
				sr = new StreamReader(ns);
				sw.WriteLine("du bist verbunden");
				sw.Flush();
			}

diesen Code Teil jeweils in einen eigenen Thread verpacken?
Aber wie? Dann brauch ich doch ein Event, was ausgelöst wird, falls ein Client neu verbindet und das event mir dann einen neuen Thread erstellt.

Ein Array von Threads kann man ja auch nicht in C# erstellen, oder?

jedenfalls klappt folgendes nicht:

Thread t[10];

@exec hast du mal irgendwo nen beispiel code wie sowas aufgebaut ist bzw genau funktioniert ?
private Nachricht | Beiträge des Benutzers
Pulpapex
myCSharp.de - Member



Dabei seit:
Beiträge: 962
Herkunft: Rostock

beantworten | zitieren | melden

Der Code, der nach Aufbau der Verbindung Daten aus dem Stream empfängt, muss in einen eigenen Thread, nicht die ganze Schleife. Die erforderlichen Codezeilen zum Erstellen und Starten des Threads können direkt nach der Zeile mit TcpListener.AcceptTcpClient eingefügt werden. Es werden also keine Events oder ähnliches benötigt.

Ablauf:
- Schleife wartet auf Verbindung (AcceptTcpClient blockiert).
- Schleife nimmt Verbindung an.
- Datenübertragung über Verbindung erfolgt in neuem Thread.
- Schleife wartet schon auf die nächste Verbindung.

Zitat
Thread t[10];
Programmierst du sonst C?
Der Arraytyp ist Thread[]. Eine Größe kann bei einer Array-Definition nicht angegeben werden, erst bei der Initialisierung. Und den Bezeichner so dazwischenklemmen geht auch nicht.

Also so ist es richtig:

Thread[] t = new Thread[10];

Gruss
Pulpapex
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

Ja ich komme aus der C welt

Hab das jetzt mit 3 Threads versucht. Einmal der Mainthread wo die MainMethode drin ist. zur darstellung des Fensters. Ein Thread der nur Verbindungen annimmt und ein Thread für jeden Client zur verarbeitung. Nur wie übergebe ich dem 3. Thread nen Parameter auf das tcplistener Objekt ??


public Thread Hauptthread;
		public Thread[] clients;
		public bool status = true;

		public void vHaupthread()
		{
			while(status==true)
			{
				TcpClient tc = tl.AcceptTcpClient();
				clients[0] = new Thread(new ThreadStart(VerarbeiteClient(tc)));
				
			}
		}	
		public void VerarbeiteClient(TcpClient pTC)
		{
			ns = pTC.GetStream();
			sw = new StreamWriter(ns);
			sr = new StreamReader(ns);
			sw.WriteLine("du bist verbunden");
			sw.Flush();
		}



		public main_form()
		{
			//
			// Erforderlich für die Windows Form-Designerunterstützung
			//
			InitializeComponent();
			tl = new TcpListener(1400);
			tl.Start();
			Hauptthread = new Thread(new ThreadStart(this.vHaupthread));
			Hauptthread.Start();	
			//clients = new Thread[10];
			
			//
			// TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu
			//
		}

Wäre der Rest sonst so richtig ?
private Nachricht | Beiträge des Benutzers
maxE
myCSharp.de - Member



Dabei seit:
Beiträge: 456
Herkunft: Sachsen

beantworten | zitieren | melden

Vom Prinzip her ja, aber du must den ClientThread natürlich noch starten.
Außerdem musst du sicherstellen, dass der eingegangene Client auch an den Thread übergeben wird.

Du kannst da noch ne extra Klasse erstellen, die das kapselt (hier mal mit Sockets):


...
while(run)
{
	Socket s = socket.Accept();
				
	WorkerThread thread = new WorkerThread();
	thread.Start(s);
}
...
public class WorkerThread
{
	private Socket socket;
	private Thread thread;
		
	public WorkerThread()
	{
		thread = new Thread(new ThreadStart(WorkerThreadProc));
	}
		
	public void Start(Socket s)
	{
		socket = s;
		thread.Start();
	}
		
	private void WorkerThreadProc()
	{
	... 
	// client bedienen
	socket.Close();
	}
...
I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

Zitat
Außerdem musst du sicherstellen, dass der eingegangene Client auch an den Thread übergeben wird.

hm ja das habe ich ja vor. Nur suche ich halt eine Möglichkeitkeit, parameter dem Thread zu übergeben. In C ist das kein Problem, da brauch ich keine extra Klasse für. Geht das nicht in C# auch ohne Klasse?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo snoopy,

ohne Klasse geht es m.E. nicht, aber ohne extra Klasse eigentlich schon:

Parameter bei Threads

herbivore
private Nachricht | Beiträge des Benutzers
snoopy
myCSharp.de - Member



Dabei seit:
Beiträge: 205
Herkunft: NRW Minden

Themenstarter:

beantworten | zitieren | melden

hab es jetzt mit ner extra klasse gemacht. funktioniert auch einwandfrei. Danke schön allen.
private Nachricht | Beiträge des Benutzers
maxE
myCSharp.de - Member



Dabei seit:
Beiträge: 456
Herkunft: Sachsen

beantworten | zitieren | melden

Ich möchte hier noch hinzufügen, dass es im .NET Framework 2.0 möglich ist auch Parameter direkt an den Thread zu übergeben:

http://msdn2.microsoft.com/library/1h2f2459(en-us,vs.80).aspx
I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.
private Nachricht | Beiträge des Benutzers