Toon posts:

[java] Multithreading client server

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben op dit moment java aan het leren. Ik wil het volgende maken in de commandline:

Een client server systeem waarbij de gebruikers via de commandline inloggen op een server en vervolgens een reis kunnen boeken. Er moeten meerdere gebruikers kunnen inloggen. Het systeem moet dus multitreading gebruiken. De code is als volgt:

code:
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
import java.io.*;
import java.net.*;

public class bookServer implements Runnable
{
    private static final int MAX_CONNECTIONS = 5;
    private Thread[] clientConnections;
    private static ServerSocket servSock;
    private static final int PORT = 1234;
    
    public static void main(String[] args)
    {
        bookServer serverTest = new bookServer();
    }

    public bookServer()
    {
        clientConnections = new Thread[MAX_CONNECTIONS];        
        
        System.out.println("Starting server....\n");
        try
        {
            servSock = new ServerSocket(PORT);
        }
        catch(IOException e)
        {
            System.out.println("Unable to start server!");
            System.exit(1);
        }
        do
        {
            try
            {
                serverStart();
            }
            catch(InvalidClientException icException)
            {
                System.out.println("Error: " + icException);
            }
            catch(InvalidRequestException irException)
            {
                System.out.println("Error: " + irException);
            }
        }while (true);
        //clientConnections[0] = new Thread(this);
        //clientConnections[0].start();
    }
    
    private void serverStart()
        throws InvalidClientException, InvalidRequestException
    {
        try
        {
            Socket link = servSock.accept();
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(
                        link.getInputStream()));
            PrintWriter out = new PrintWriter(
                link.getOutputStream(),true);
            
            String name = in.readLine();
            if(name != "")
            {
                System.out.println(name + " is trying to connect!");
                clientConnections[0] = new Thread(this);
                clientConnections[0].start();
            }
            //if (!name.equals(client1) && !name.equals(client2))
            //  throw new InvalidClientException();
            //if (!sendRead.equals("send") && !sendRead.equals("read"))
            //  throw new InvalidRequestException();
            link.close();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void run()
    {
        System.out.println(Thread.currentThread().getName() + " being executed.");
    }
}
class InvalidClientException extends Exception
{
    public InvalidClientException()
    {
        super("Invalid client name!");
    }
    public InvalidClientException(String message)
    {
        super(message);
    }
}

class InvalidRequestException extends Exception
{
    public InvalidRequestException()
    {
        super("Invalid request!");
    }
    public InvalidRequestException(String message)  
    {
        super(message);
    }
}


De server luistert op een socket, en de client stuurt zijn naam. De server start nu automatisch een thread. Maar nu (of die ik het helemaal verkeerd) moet deze thread kunnen communiceren met de client die deze thread gestart heeft. Moet ik nu in de thread een andere socket openen en opnieuw een connectie maken met de client? of kan ik op dezelfde socket communiceren door bij iedere communicatie de client naam waarmee hij inlogt mee te sturen zodat de rest dit kan negeren?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Zonder op de inhoud te letten, waarom zou je in godsnaam met sockets willen werken? Pak in ieder geval een hogere middelware variant zoals RMI ofzo (alhoewel dat eigelijk ook nog te laag is)

Verder moet je enorm oppassen met threads. Threads zijn noodzakelijk, maar probeer ze zoveel mogelijk te vermijden als het niet nodig is. Als jouw acties niet al te lang duren en ze asynchroon opgelost mogen worden, zou jij bv een synchronized queue kunnen maken waarop de 'threads-van-de-client' hun verzoek tot info posten. Aan deze queue plak je een counting semafoor die dus luisterd naar verzoektjes. De afhandeling van deze verzoeken gan gebeuren binnen de hoofdthread van de applicatie, maw je hebt afgezien van die messagequeue niets meer te maken met theads..

Deze patterns staat ook wel bekend als de reactor pattern als je daarin geinteresseerd bent.

[ Voor 70% gewijzigd door Alarmnummer op 20-02-2004 11:53 ]


Verwijderd

Topicstarter
Ik ben java aan het leren voor mijn opleiding. Het is een vereiste dat het op deze manier moet gebeuren om te leren met threads om te gaan. Ook de socket is verplicht. Wat ik me echter afvraag is of de constructie die in gebruik klopt?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op 20 februari 2004 @ 11:42:
Ik ben java aan het leren voor mijn opleiding. Het is een vereiste dat het op deze manier moet gebeuren om te leren met threads om te gaan.
Heb je concurrency control gehad? Zo nee, dan zeg maar tegen je leraar dat ie een ander beroep moet gaan zoeken omdat ie er geen snars van snapt. Zo ja.. dan moet je verdomt goed nadenken over hoe je threads gaat inzetten, je hebt zo veel gedonder met race problemen en deadlocks.. daar word je echt niet blij van.
Ook de socket is verplicht. Wat ik me echter afvraag is of de constructie die in gebruik klopt?
Ik doe nooit iets met sockets :) Ik kan je daar dus niet mee helpen.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 26-05 00:01

Janoz

Moderator Devschuur®

!litemod

Waarom gebruik je 1 class? Ikzelf zou eerder de boel opdelen in een server die de sockets accepteerd en vervolgens voor elke binnenkomende socket een handler oid maken en die starten. Deze andler krijgt dan de socket (of alleen de in en output) mee.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • B-Man
  • Registratie: Februari 2000
  • Niet online
Alarmnummer schreef op 20 februari 2004 @ 11:34:
Verder moet je enorm oppassen met threads. Threads zijn noodzakelijk, maar probeer ze zoveel mogelijk te vermijden als het niet nodig is. Als jouw acties niet al te lang duren en ze asynchroon opgelost mogen worden, zou jij bv een synchronized queue kunnen maken waarop de 'threads-van-de-client' hun verzoek tot info posten. Aan deze queue plak je een counting semafoor die dus luisterd naar verzoektjes. De afhandeling van deze verzoeken gan gebeuren binnen de hoofdthread van de applicatie, maw je hebt afgezien van die messagequeue niets meer te maken met theads..
Dan kun je net zo goed met NIO werken, dan hoef je ook geen thread-per-client meer te hanteren. Al zit je dan nog steeds behoorlijk "low-level" te werken.

Verwijderd

Topicstarter
Okay,

dus ik moet vanuit een class server, die de connections accept, een handler starten die vervolgens met de client communiceert op dezelfde socket als de server? Hoe maak ik deze socket van de server beschikbaar in de thread, of kan ik simpelweg deze opniew openen?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 21:44

Robtimus

me Robtimus no like you

Verwijderd schreef op 20 februari 2004 @ 12:07:
Okay,

dus ik moet vanuit een class server, die de connections accept, een handler starten die vervolgens met de client communiceert op dezelfde socket als de server? Hoe maak ik deze socket van de server beschikbaar in de thread, of kan ik simpelweg deze opniew openen?
In je BookServer:
Java:
1
2
3
4
5
6
7
8
public void run()
{
    while (true)
    {
        Socket sock = servSock.accept();
        new Handler(sock).start();
    }
}
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Handler extends Thread
{
    private Socket sock;
    public Handler(Socket sock)
    {
        this.sock = sock;
    }

    public void run()
    {
        // doe iets met sock
    }
}

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Op de manier zoals je nu werkt, zul je telkens opnieuw een thread moeten starten en creëren, omdat een thread een afgebakende taak heeft. Voor jou is het makkelijker om een thread te maken waarin je jobs kan pluggen, oftewel een threadpool. Zie daarvoor http://www.codebase.nl/index.php/command/viewcode/id/222 , hoewel je nu nog weinig doet met je threads

Verder is dus de Socket link, die je krijgt van accept() je verbinding van en naar de client.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 21:44

Robtimus

me Robtimus no like you

Glimi schreef op 20 februari 2004 @ 13:27:
Op de manier zoals je nu werkt, zul je telkens opnieuw een thread moeten starten en creëren, omdat een thread een afgebakende taak heeft. Voor jou is het makkelijker om een thread te maken waarin je jobs kan pluggen, oftewel een threadpool. Zie daarvoor http://www.codebase.nl/index.php/command/viewcode/id/222 , hoewel je nu nog weinig doet met je threads

Verder is dus de Socket link, die je krijgt van accept() je verbinding van en naar de client.
Thanx, ik had al een ThreadPool nodig voor mijn opdracht. Ik zal er eens goed naar kijken.

Ik gaf dit alleen als voorbeeldje, daarvoor kun je natuurlijk nog veel optimaliseren (zoals een TP).

PS: maar 1 PoolListener? Sneu hoor ;)

[ Voor 3% gewijzigd door Robtimus op 20-02-2004 13:33 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
IceManX schreef op 20 februari 2004 @ 13:30:
PS: maar 1 PoolListener? Sneu hoor ;)
offtopic:
Dat gaf om een of andere een listmodifiedException als ik daar een list voor gebruikte, daar kwam ik toen even niet meer uit.
Verbeteringen zijn altijd welkom natuurlijk :+
Pagina: 1