Multithreaded SocketServer

Status
Niet open voor verdere reacties.

kwitter

Nieuwe gebruiker
Lid geworden
12 dec 2009
Berichten
1
Dit is een van mijn eerste projectjes in Java, en ik probeer een multithreaded socketserver te maken.
Ik loop enkel tegen wat probleempjes,

1: Wanneer een client de verbinding verbreekt, stop ik de while-lus, en haal ik de verbinding uit de connectionTable, echter blijft mijn thread nu nog levendig? En hoe zet ik die op stop?

2: Wanneer een client de verbinding verbreekt krijg ik een 'null', hij zegt "I Got: null" en de lijn eronder "Client dropped", normaal gezien wordt de while lus toch verbroken voordat hij aan I got geraakt.

3: Als ik iets stuur en druk op enter zegt hij "i got: ..." Dit is dus ok, maar wanneer ik de tweede maal wat stuur zegt hij niet, de derde maal zegt hij weer "i got:..." dus op de oneven verzonden berichten reageerd hij... Hoe komt dit?

Alvast bedankt voor de hulp!

Code:
import java.net.*;
import java.io.*;
import java.util.*;

public class SocketServer 
{
    //Server Variables
    static Vector connectionTable;
    static int nextConnectionID = 1;

    public SocketServer(int port)
    {
        ServerSocket socketServer = null;
        Socket socket = null;
        connectionTable = new Vector();

        try
        {
            socketServer = new ServerSocket(port);
            while ((socket = socketServer.accept()) != null)
            {
                ClientThread now;
                Thread current = new Thread(now = new ClientThread(socket));
                current.setDaemon(true);
                connectionTable.addElement(now);
                current.start();
            }
        }
        catch (Exception e)
        {
            System.err.println(e);
            System.exit(1);
        }
    }
	
}

class ClientThread extends Thread
{
    //Thread Variables
    private Socket linkTo;		//The Socket
    private int connectionID;
    private String line;

    public ClientThread(Socket from)
    {
        connectionID = SocketServer.nextConnectionID++;
        linkTo = from;
        System.out.println(linkTo);
        System.out.println(connectionID);
        ClientIn();
    }
	
    public void ClientIn()
    {
        while(true)
        {
            try
            {
                // Get input from the client
                DataInputStream in = new DataInputStream (linkTo.getInputStream());
                if(in.readLine() == null){
                    System.out.println("Client dropped!");
                    linkTo.close();
                    SocketServer.connectionTable.removeElement(this);
                    break;
                    //Client stoppen
                }
                else
                {
                    System.out.println("I got:" + in.readLine());
                    
                }
            } catch (IOException ioe) {
                System.out.println("IOException on socket listen: " + ioe);
                ioe.printStackTrace();
            }
        }
    }
}
 
2: Wanneer een client de verbinding verbreekt krijg ik een 'null', hij zegt "I Got: null" en de lijn eronder "Client dropped", normaal gezien wordt de while lus toch verbroken voordat hij aan I got geraakt.

Ik ben zelf ook nog een beginner, sowieso op het gebied van sockets dus ik kan ook niet garanderen dat wat ik zeg goed is, maar volgens mij komt hij nooit uit die while loop.
Het is een oneindige loop ( while(true) want dat blijft altijd waar), daarom geeft hij volgens mij ook die "I got" eerst wel dan niet en daarna wel weer, als je input null is word het if statement uitgevoerd, als hij !null (ongelijk aan null is) word de else uitgevoerd, maar omdat jou while loop altijd doorblijft "loopen" blijft hij dat uitvoeren en komt hij niet verder in het programma. Volgens mij is de while hier dus onnodig, (De if en else horen bij elkaar, niet de while en else (ik denk dat je daar een denkfout maakt?).

Wat je volgens mij wel kan doen is:
de if herschrijven naar een while. while(de input == null) dan blijft hij het uitvoeren zolang de input null is (dus hij blijft controleren, maar raakt uit de loop als de input !null is)
Of je zou de while weg kunnen laten.
Bij een if controleert hij een keer, hij doorloopt hem en als het niet zo is (de if word false) gaat het programma uit de if en gaat hij verder (in dit geval naar de else).
Bij een while blijft hij controleren zolang iets waar is, bij jou is het altijd waar en blijft hij dus doorgaan :)

ps. Welkom op het forum.

M.v.g.
NewbProgr
 
Laatst bewerkt:
Als je met threads gaat werken kan je het beste de interface runnable implementeren ipv de thread te extenden.

Thread t = new Thread( new Runner())
t.start()

Runner implements Runable.
...

De runnable interface heeft maar 1 functie nml run().

Dit is namelijk de functie die thread wordt uigevoerd. Als de run() functie klaar is eindigt die thread. Dit is de enige echte manier om een thread te stoppen. (de thread.stop() is deprecated omdat dit deadlocks kon veroorzaken...)
 
Je gebruikt 2x in.readLine() hierdoor leest jouw server 2 verschillende zinnen, hierdoor test hij eerst de ene zin of deze null is en daarna leest hij de volgende zin bij "I Got:" dit kun je oplossen door het resultaat van in.readLine() in een variable te zetten .

Verder is beter om DataInputStream in = new DataInputStream (linkTo.getInputStream()); buiten de while loop te zetten zodat je deze niet de hele tijd overschrijft, wat onnodig is.
Ook kun je beter in plaats van DataInputStream een BufferedReader gebruiken omdat de readLine methode van DataInputStream deprecated is. (zie de java docs)
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan