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
Socket Server Multiclientfähig
guest
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

Socket Server Multiclientfähig

beantworten | zitieren | melden

Hallo, ich bin im Networking noch sehr neu und möchte euch fragen wie ich einen Server Multiclientfähig machen kann?
Erstmal meinen Server:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Threading;
using Client;

namespace Server
{
    class Program1
    {
        
        static void Main(string[] args)
        {

            DateTime d1 = DateTime.UtcNow;
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken ct = cts.Token;
            
            try
            {

                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),3123));
                sock.Listen(1000);
                Console.WriteLine("[{0}] >> Server wartet auf Verbindungswunsch", d1.TimeOfDay);
                        
                    
                Task.Factory.StartNew(receive =>
                {

                    try
                    {
                        Socket cS = sock.Accept();
                        Console.WriteLine("[{0}] >> Client Connected", d1.TimeOfDay);
                        while (true)
                        {

                            byte[] buffer = new byte[256];
                            int bytes = cS.Receive(buffer);
                            Console.WriteLine("[{1}] >> {0}", ASCIIEncoding.ASCII.GetString(buffer, 0,  bytes), d1.TimeOfDay);
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Client disconncted");
                    }
                }, ct);
                
            }
            catch (Exception ex)
            {
                
                Console.WriteLine(ex.Message,"Exception");
            }
            Console.Read();
        }

    }
}
Wenn ich mich jetzt mit einem Client verbinde und ich mit dem Server "chatte" funktioniert alles super.
Doch, wenn ich mich mit einem zweiten Client verbinde funktioniert es nichtmehr, bzw. beim Server kommen die Nachrichten nicht an, und es wird beim Server auch kein weiteres "Client connected" ausgegeben.
Wie muss ich das machen?
Ich hab schon gegooglet, youtube videos gesucht, bei msdn geschaut. Doch ich finde nichts konkretes dazu.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von guest am .
extinct
private Nachricht | Beiträge des Benutzers
Diräkt
myCSharp.de - Member



Dabei seit:
Beiträge: 611
Herkunft: Schweiz

beantworten | zitieren | melden

Hallo guest

Schau Dir doch mal folgende Beiträge an :
Lauscht der TCPListener permanent nach Verbindungen?

Kleines Chat Program

Beste Grüsse

Diräkt
private Nachricht | Beiträge des Benutzers
Cat
myCSharp.de - Member

Avatar #avatar-3070.jpg


Dabei seit:
Beiträge: 771

beantworten | zitieren | melden

Hi,

du mußt nach Socket.Accept einen neuen Thread (bzw. Task) starten und dann im Hauptthread wieder diese Methode aufrufen:


while(true)
{
  Socket socket = sock.Accept();

  Task.Factory.StartNew(s =>
  {
    while (true)
    {
       byte[] buffer = new byte[256];
       int bytes = s.Receive(buffer);
       Console.WriteLine("[{1}] >> {0}", ASCIIEncoding.ASCII.GetString(buffer, 0,  bytes), d1.TimeOfDay);
    }
  },
  socket);
}
private Nachricht | Beiträge des Benutzers
guest
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

@Diräkt: Danke fuer deine Antwort, aber ich moechte TcpListener eigentlich vermeiden, da die Klasse etwas alt ist, Socket ist da bischen moderner.
@ Cat:


Also Soll das dann so aussehen?:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Threading;
using Client;

namespace Server
{
    class Program1
    {

        static void Main(string[] args)
        {

            DateTime d1 = DateTime.UtcNow;
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken ct = cts.Token;

            try
            {

                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),3123));
                sock.Listen(1000);
                Console.WriteLine("[{0}] >> Server wartet auf Verbindungswunsch", d1.TimeOfDay);


                Task.Factory.StartNew(receive =>
                {

                    try
                    {

                        while (true)
                        {
                        Socket cS = sock.Accept();
                        Console.WriteLine("[{0}] >> Client Connected", d1.TimeOfDay);
Task.Factory.StartNew(s=>
{
while(true){
                            byte[] buffer = new byte[256];
                            int bytes = cS.Receive(buffer);
                            Console.WriteLine("[{1}] >> {0}", ASCIIEncoding.ASCII.GetString(buffer, 0,  bytes), d1.TimeOfDay);
}
},cS);
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Client disconncted");
                    }
                }, ct);

            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message,"Exception");
            }
            Console.Read();
        }

    }
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von guest am .
extinct
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.778
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Cat und guest,

wenn hier Tasks verwendet werden, so sollte als TaskCreationOption LongRunning verwendet werden, da somit ein eigener Thread erstellt wird und keiner aus dem ThreadPool verwendet wird. ThreadPool-Thread sollten eher für kurze Aufgaben (ein paar Zehntelsekunden) verwendet werden und hier ist Lebensdauer des Tasks i.d.R. wohl deutlich höher.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
guest
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Danke fuer den Tipp gfoidl.
Aber wird dann auch einen Hintergrundtask erzeugt? Oder beeinflusst die Option longrunning das?
Weil wenn man ja einen Task erzeugt, wird dieser ja zum Hintergrundtask, automatisch

Und wiederum zur anderen Frage, ist der Code den ich gepostet habe korrekt? Augenommen, dass die option longrunning nicht aktiviert ist.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von guest am .
extinct
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.778
Herkunft: Waidring

beantworten | zitieren | melden

Hallo guest,

mit LongRunning ist es auch ein Hintergrund-Thread. Bei Tasks gibt es die Unterscheidung Vorder-/Hintergrund nicht, nur bei Threads.

Obs korrekt ist, weiß ich nicht, da ich mich mit Sockets nicht so gut auskenne. Da weiß Cat od. Diräkt sicher mehr zu berichten.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Diräkt
myCSharp.de - Member



Dabei seit:
Beiträge: 611
Herkunft: Schweiz

beantworten | zitieren | melden

Hallo guest

Hier hast du ein perfektes Beispiel ( schau mal die Methode StartListening() an )
Using an Asynchronous Server Socket

Beste Grüsse

Diräkt
private Nachricht | Beiträge des Benutzers
jogibear9988
myCSharp.de - Member



Dabei seit:
Beiträge: 580
Herkunft: Offenau

beantworten | zitieren | melden

Zitat von guest
@Diräkt: Danke fuer deine Antwort, aber ich moechte TcpListener eigentlich vermeiden, da die Klasse etwas alt ist, Socket ist da bischen moderner.

Wo steht das? Ichdenke Socket Ist da einfach ein Level weniger Abstrahiert! Aber TCPListener veraltet??
cSharp Projekte : https://github.com/jogibear9988
private Nachricht | Beiträge des Benutzers
pdelvo
myCSharp.de - Member

Avatar #avatar-3354.png


Dabei seit:
Beiträge: 1.346

beantworten | zitieren | melden

Generell ist es aber nicht wirklich gut Threads dafür zu verschwenden auf eine Netzwerkanfrage zu warten. Da ist das benutzen von asynchronen Methoden deutlich sparsamer. Wenn man C# 5 zur Verfügung hat sieht die asynchrone Variante ohne Threads fast genau so aus
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,
Zitat
aber ich moechte TcpListener eigentlich vermeiden, da die Klasse etwas alt ist, Socket ist da bischen moderner.
Das stimmt so nicht. Die Klassen TcpListener/TcpClient verwenden intern auch Socket, nur dass ein Socket eben noch viel mehr kann als Tcp => die beiden Klassen sind genau dafür da, für Tcp-Verbindungen den Zugriff auf die Sockets zu vereinfachen. Solange Du bei Tcp bleiben willst, gibt es überhaupt keinen Grund, direkt mit den Sockets zu arbeiten.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
guest
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Zitat
Hier hast du ein perfektes Beispiel ( schau mal die Methode StartListening() an )
Using an Asynchronous Server Socket
Also ich sehe und kenne keine Methode die StartListening heißt. Sofern du die Klasse Socket meinst
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von guest am .
extinct
private Nachricht | Beiträge des Benutzers
weismat
myCSharp.de - Member



Dabei seit:
Beiträge: 872
Herkunft: Frankfurt am Main

beantworten | zitieren | melden

Socket ist ein C#-Wrapper um die native Winsocket 2 Klasse . Diese Socket Klasse unterstuetzt mit einem API verschiedene Transport-Protokolle (z.B. TCP und UDP). Weiterhin kann ein Socket sowohl fuer Server als auch Client Anwendungen genutzt werden.
Ein TCPListener ist eine spezielle C# Komponente fuer TCP Server basierend auf Sockets. Wie Du selber gemerkt hast, ist das TCPListener Protokoll spezieller als das von Socket auf einen TCP Server abgestimmt. Start waere z.B. ein Bind und dann ein Listen mit bestimmten Flags.
Edit:
Falls es Dich interessiert, kannst Du Dir auch mit dem ILSpy die Implementierung von TCPListener anschauen/angepasst verwenden.
MSDN sagt so schoen:
Zitat
If you are writing a relatively simple application and do not require maximum performance, consider using TcpClient, TcpListener, and UdpClient. These classes provide a simpler and more user-friendly interface to Socket communications.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von weismat am .
private Nachricht | Beiträge des Benutzers