Avatar billede lasserasch Juniormester
18. april 2007 - 05:30 Der er 6 kommentarer og
1 løsning

WinSock til C# (Flere samtidige Forbindelser).

Hejsa.

Nu har jeg brugt over 24 timer, og er stadig ikke kommet ordenligt igang, så derfor kommer der nu et spørgsmål her i stedet for.

Jeg er ved at lære mig selv lidt netværksprogrammering.

Nærmere bestemt Winsock. Jeg har fundet en WinSock component som kører super godt i mit C# .NET program jeg udvikler i VS 2005.

Jeg har lavet en lille server og en klient.

Jeg kan starte min server, lytte, modtager 1 forbindelse og sende data begge veje. Så alt dette er jo godt nok.


Men jeg mangler altså stadig at finde en løsning på hvordan jeg kan håndtere flere klienter på min server på en gang. Jeg har læst en masse mindre forståelige artikler omkring at jeg skal lave et array og lave en ny Winsock forbindelse når min server modtager et connection request.

Men jeg kan kun finde nogle meget advancerede eksempler i VB og de fleste af dem i noget meget forældet VB 6.0.

Findes der ikke en herinde, som kan give et MEGET simpelt eksempel på en C# kode til min server, som kan håndtere flere klienter på en gang?

Håber virkelig at der er en som kan hjælpe, for jeg er ved at blive helt ør' i hovedet af alt det læsning nu!!!

/Lasse
Avatar billede lasserasch Juniormester
18. april 2007 - 05:35 #1
Min nuværende Server kode :

-----------------

    public partial class Form1 : Form
    {
        Winsock2005DLL.Winsock Sock1 = new Winsock2005DLL.Winsock();

        public Form1()
        {
            InitializeComponent();
            Sock1.LocalPort = 700;
            Sock1.DataArrival += new Winsock2005DLL.Winsock.DataArrivalEventHandler(Sock1_DataArrival);
            Sock1.ConnectionRequest += new Winsock2005DLL.Winsock.ConnectionRequestEventHandler(Sock1_ConnectionRequest);
        }

        void Sock1_DataArrival(object sender, Winsock2005DLL.WinsockDataArrivalEventArgs e)

        {
            string data = "";
            Sock1.Get(ref data);
            switch (data.Substring(0, 5))
            {
                case "CMD01": Sock1.Send("Svar på CMD01"); break;
                case "CMD02": Sock1.Send("Svar på CMD02"); break;
                case "CMD03": Sock1.Send("Svar på CMD03"); break;
                default: Sock1.Send("Unknown Command"); break;
            }
        }
        void Sock1_ConnectionRequest(object sender, Winsock2005DLL.WinsockClientReceivedEventArgs e)
        { 
            Sock1.Accept(e.Client);
        }
   
        private void Form1_Load(object sender, EventArgs e)
        {
        Sock1.Listen();
        }

    }

-----------
Avatar billede mr-kill Nybegynder
18. april 2007 - 08:23 #2
Det du skal gøre er at give hver client deres egen tråd på serveren. Jeg har fundet et meget brugt eksempel fra dette forum, som viser det meget godt. Denne kode bruger dog TcpClient til at lave forbindelsen, men det skulle være meget let at passe til så du kan bruge det :)

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

class ChatMain
{
    public static void Main(string[] args)
    {
        Server srv = new Server();
        srv.Run();
    }
}

class Server
{
    private ArrayList allclients;
    public void Run()
    {
        allclients = new ArrayList();
        TcpListener server = new TcpListener(IPAddress.Any, 50000);
        server.Start();
        while(true)
        {
            TcpClient client = server.AcceptTcpClient();
            ClientHandler ch = new ClientHandler(client, this);
            allclients.Add(ch);
            (new Thread(new ThreadStart(ch.Run))).Start();
        }
    }
    public void SendAll(string msg)
    {
        foreach(ClientHandler ch in allclients)
        {
            ch.Send(msg);
        }
    }
    public void Remove(ClientHandler ch)
    {
        allclients.Remove(ch);
    }
}

class ClientHandler
{
    private StreamReader rdr;
    private StreamWriter wrt;
    private Server srv;
    public ClientHandler(TcpClient cli, Server srv)
    {
        rdr = new StreamReader(cli.GetStream());
        wrt = new StreamWriter(cli.GetStream());
        this.srv = srv;
    }
    public void Run()
    {
        while(true)
        {
            string line = rdr.ReadLine();
            string cmd = line.Split(" ".ToCharArray())[0];
            if(cmd == "SEND")
            {
                srv.SendAll(line.Substring(5));
            }
            else if(cmd == "EXIT")
            {
                srv.Remove(this);
                return;
            }
        }
    }
    public void Send(string msg)
    {
        lock(wrt)
        {
            wrt.WriteLine(msg);
            wrt.Flush();
        }
    }
}
Avatar billede lasserasch Juniormester
18. april 2007 - 15:52 #3
Okay, ja det lyder jo logisk nok at bruge flere tråde for ikke at blokere serveren hvis en klientforbindelse skal overføre store mængder data.

Nu er det her måske et totalt dumt spørgsmål, men er det mig der har fat i den forkerte løsning, når jeg leger med Winsock i C# .net?? Eller hvad er forskellen på TCPServer, som vist herover og WinSock?

Det eneste jeg skal bruge den til, er at sende kommandoer til serveren, som så skal udføre en handling. F.eks. SQL forespørgelse, og retunere en streng til klienten med et eller andet form for svar. F.eks. i noget XML syntaks.

Er det bedre/mere moderne at bruge TCPServer til det?

/Lasse
Avatar billede lasserasch Juniormester
18. april 2007 - 19:15 #4
Hmmm.... Kan stadig ikke få det til at virke. Kun i begrænset omfang, ved at lave f.eks. 100 Winsock referencer og hver gang en klient så forbinder, så kan jeg få den til at videregive socket forbindelsen fra den lyttende forbindelse til en af de andre.

Men det er bestemt ingen holdbar løsning.

Hvis du er hård til Winsock, kan du så ikke prøve at vise mig et eksempel ud fra min kode, som du mener burde virke?

Som sagt, det behøves ikke være noget fancy, men det her med nye threads og hvordan man styrer dette er mig lidt en gåde. Så et fungerende eksempel ville være mega rart!

/Lasse
Avatar billede lasserasch Juniormester
19. april 2007 - 04:19 #5
Nå, så fandt jeg sgu selv ud af det tror jeg!

Har ikke rigtig kunnet få den overstående kode til at fungere, men fandt et andet og lidt mere advanceret eksempel, som jeg har plukket lidt kode ud af. Og nu ser det ud til at køre... Med flere tråde, Hashtable over tråde og et over sockets osv...

Hmmm... Mon man kan lægge sin kode på eksperten.dk til andre, så de kan se og downloade et fungerende resultat?

Puha, det var en forvirrende omgang, men jeg er vist ikke den eneste der er løbet ind i problemer omkring dette emne.

/Lasse
Avatar billede mr-kill Nybegynder
19. april 2007 - 14:08 #6
Jeg aner intet om Winsock, beklager...

Hvis du selv fandt løsningen og ikke kunne bruge min, så ta du bare point selv ;)
Avatar billede lasserasch Juniormester
20. april 2007 - 09:03 #7
Jeg fandt selv løsningen, men det blev bare ikke en eller anden winsock komponent. Fandt jo ud af at .NET frameworket har alt hvad man skal bruge...

Jeg har lavet et eksempel program (Server/Klient), som viser hvordan det kan laves...
Så hvis andre skulle have behov for samme løsning, så kan det downloades her :

www.skare.dk/tcpkommunikation.zip


/Lasse
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester