Socket Änderung an Netzwerkchat führt zu Fehlern

mac21

Aktives Mitglied
Hallo Liebe Community,
habe einen Netzwerkchat aus dem netz weiter- bzw. umprogrammiert. Original arbeitete er mit Input- und Outpustreams.
Jedoch wollte ich die beiden durch BufferedReader und PrintWriter ersetzen, weil diese wohl besser geeignet wären und ich diese für die weitere programmentwicklung benötige. (Stichwort: UTF-8) :D
Um den Client liegt noch eine Frame.java, welche das GUI bereitstellt (ist jedoch hierfür nicht nötig).

Die "originalen" Klassen lauten:

Client:
Java:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

public class MultiThreadChatClient implements Runnable{
    
    // Declaration section
    // clientClient: the client socket
    // os: the output stream
    // is: the input stream
    
    static Socket clientSocket = null;
    static PrintStream os = null;
    static DataInputStream is = null;
    static BufferedReader inputLine = null;
    static boolean closed = false;
    static Frame frm;
    static boolean status = false;
    static String username;
    static List<String> user = new ArrayList<String>();
    
    public static void main(String[] args) {
	
    	frm = new Frame();
    	try{
    		PrintStream printStream = new PrintStream(new CustomOutputStream(frm.chatTextArea));
    		System.setOut(printStream);
    	}catch(Exception e){}
		Listener();
		
    	// The default port	
	
	int port_number=2222;
        String host="192.168.50.156";
	
	if (args.length < 2)
	    {
		System.out.println("Server: " + host + ", Port: " + port_number);
	    } else {
		host=args[0];
		port_number=Integer.valueOf(args[1]).intValue();
	    }
	// Initialization section:
	// Try to open a socket on a given host and port
	// Try to open input and output streams
	try {
            clientSocket = new Socket(host, port_number);
            //inputLine = new BufferedReader(new InputStreamReader(System.in));
            os = new PrintStream(clientSocket.getOutputStream(),true,"utf-8");
            is = new DataInputStream(clientSocket.getInputStream());
        } catch (UnknownHostException e) {
            System.err.println("Kann Host nicht finden: " + host);
        } catch (IOException e) {
            System.err.println("Kann Host nicht erreichen: " + host);
        }
	
	// If everything has been initialized then we want to write some data
	// to the socket we have opened a connection to on port port_number 
	
        if (clientSocket != null && os != null && is != null) {
            try {
            
		
		// Create a thread to read from the server
		
                new Thread(new MultiThreadChatClient()).start();
                
		while (!closed) {
                   //os.println(inputLine.readLine());
			if(status == true){
				os.println("#check:"+username);
				try{
					Thread.sleep(4000);
				}catch(Exception e){}
			}
		}
		
		// Clean up:
		// close the output stream
		// close the input stream
		// close the socket
		
		os.close();
		is.close();
		clientSocket.close();   
            } catch (IOException e) {
                System.err.println("IOException:  " + e);
            }
        }
    }           
    
    public void run() {		
	String responseLine;
	
	// Keep on reading from the socket till we receive the "Bye" from the server,
	// once we received that then we want to break.
	try{ 
	    while ((responseLine = is.readLine()) != null) {
	    if(responseLine.contains("#check")) {addInList(responseLine);}
		else{
				System.out.println(responseLine);
		}
		if (responseLine.indexOf("Bye") != -1) {break;}
		if (responseLine.indexOf("offline") != -1) {removeFromList(responseLine);}
	    }
            closed=true;
            try{
            	frm.disconnectButton.setEnabled(false);
            	frm.connectButton.setEnabled(false);
            	frm.sendButton.setEnabled(false);
            	frm.inputTextArea.setEnabled(false);
            	frm.chatTextArea.setEnabled(false);
            	Thread.sleep(2500);
            }catch(Exception e){System.exit(-1);};
            
            System.exit(1);
	} catch (IOException e) {
	    System.err.println("IOException:  " + e);
	}
    }
    
    public void addInList(String input){
    	String[] temp = new String[2];
    	temp = input.split(":");
    	if(user.indexOf(temp[1])==-1)
    	{
    		user.add(temp[1]);
    	}
    	String userString = "";
    	for(String current: user){
    		userString = userString + current + "\n";
    	}
    	frm.usersList.setText(null);
    	frm.usersList.setText(userString);
    }
    
    public void removeFromList(String input){
    	String[] temp = new String[3];
    	temp = input.split("_");
    	if(user.indexOf(temp[1]) != -1)
    	{
    		user.remove(temp[1]);
    	}
    }
    
    public static void Listener() {
    	
    	frm.connectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            os.println(frm.usernameField.getText());
            username = frm.usernameField.getText();
            frm.connectButton.setEnabled(false);
            frm.usernameField.setEnabled(false);
            frm.disconnectButton.setEnabled(true);
            frm.sendButton.setEnabled(true);
            frm.inputTextArea.setEnabled(true);
            frm.inputTextArea.requestFocus();
            frm.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
            status = true;
            }
        });
    	
    	frm.disconnectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	os.println("/quit");
            }
        });
    	
    	frm.usernameField.addKeyListener(new KeyListener() {
    	    public void keyPressed(KeyEvent e) {}
    	    public void keyReleased(KeyEvent e) {
    	    	if (e.getKeyCode() == KeyEvent.VK_ENTER) {frm.connectButton.doClick();}
    	    }
    	    public void keyTyped(KeyEvent e) {}
    	});	
    
    	frm.inputTextArea.addKeyListener(new KeyListener() {
    	    public void keyPressed(KeyEvent e) {}
    	    public void keyReleased(KeyEvent e) {
    	    	if (e.getKeyCode() == KeyEvent.VK_ENTER) 
    	    	{
    	    		if(e.isShiftDown()){
    	    			frm.inputTextArea.append("\n");
    	    		}else{
    	    			frm.inputTextArea.setText(frm.inputTextArea.getText().substring(0, frm.inputTextArea.getText().length()-1));
    	    			if(frm.inputTextArea.getText().length()>0){
    	    			frm.sendButton.doClick();}
    	    		}
    	    	}
    	    }
    	    public void keyTyped(KeyEvent e) {}
    	});
    	
    	frm.sendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	os.println(frm.inputTextArea.getText());
            	frm.inputTextArea.setText(null);
            }
        });
    	
    }
}

Server:
Java:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

public class MultiThreadChatServer{

    // Declaration section:
    // declare a server socket and a client socket for the server
    // declare an input and an output stream

    static  Socket clientSocket = null;
    static  ServerSocket serverSocket = null;
    
    // This chat server can accept up to 10 clients' connections

    static  clientThread t[] = new clientThread[10];           
        
    public static void main(String args[]) {
	
	// The default port

	int port_number=2222;
	
	if (args.length < 1)
	    {
		System.out.println("Serverport: " + port_number);
	    } else {
		port_number=Integer.valueOf(args[0]).intValue();
	    }
	
	// Initialization section:
	// Try to open a server socket on port port_number (default 2222)
	// Note that we can't choose a port less than 1023 if we are not
	// privileged users (root)

        try {
	    serverSocket = new ServerSocket(port_number);
        }
        catch (IOException e)
	    {System.out.println(e);}
	
	// Create a socket object from the ServerSocket to listen and accept 
	// connections.
	// Open input and output streams for this socket will be created in 
	// client's thread since every client is served by the server in
	// an individual thread
	
	while(true){
	    try {
		clientSocket = serverSocket.accept();
		for(int i=0; i<=9; i++){
		    if(t[i]==null)
			{
			    (t[i] = new clientThread(clientSocket,t)).start();
			    break;
			}
		}
	    }
	    catch (IOException e) {
		System.out.println(e);}
	}
    }
} 

// This client thread opens the input and the output streams for a particular client,
// ask the client's name, informs all the clients currently connected to the 
// server about the fact that a new client has joined the chat room, 
// and as long as it receive data, echos that data back to all other clients.
// When the client leaves the chat room this thread informs also all the
// clients about that and terminates. 

class clientThread extends Thread{
    
    DataInputStream is = null;
    PrintStream os = null;
    Socket clientSocket = null;       
    clientThread t[]; 
    
    
    
    public clientThread(Socket clientSocket, clientThread[] t){
    	
    	
    	this.clientSocket=clientSocket;
        this.t=t;
    }
    
    public void run() 
    {
    	String line;
        String name;
        
	try{
	    is = new DataInputStream(clientSocket.getInputStream());
	    os = new PrintStream(clientSocket.getOutputStream());
	    os.println("");
	    name = is.readLine();
	    os.println("Hallo _" + name +"_");
	    for(int i=0; i<=9; i++)
		if (t[i]!=null && t[i]!=this) {  
		    t[i].os.println("*** _" + name + "_ ist jetzt online ! ***" );
		}
	    while (true) {
		line = is.readLine();
                if(line.startsWith("/quit")) break; 
		for(int i=0; i<=9; i++)
		    if (t[i]!=null)  {
		    	t[i].os.println("<"+name+"> "+line);
		    }
	    }
	    for(int i=0; i<=9; i++)
		if (t[i]!=null && t[i]!=this){  
		    t[i].os.println("*** _" + name + "_ ist jetzt offline ! ***");
		}
	    os.println("*** Bye " + name + " ! ***");
	    // Clean up:
	    // Set to null the current thread variable such that other client could
	    // be accepted by the server

	    for(int i=0; i<=9; i++)
		if (t[i]==this) t[i]=null;  
		
	    // close the output stream
	    // close the input stream
	    // close the socket
	    
	    is.close();
	    os.close();
	    clientSocket.close();
	}
	catch(IOException e){};
    }
}

somit funzt der chat nahezu einwandfrei.
Ich habe schon viel gebastelt, denn am anfang hatte er keine anzeige, welcher user online ist etc.

eine änderung (wie oben beschrieben) ergibt folgendes:

Client:

Java:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

public class KopieVonMultiThreadChatClient implements Runnable{
    
    // Declaration section
    // clientClient: the client socket
    // os: the output stream
    // is: the input stream
    
    static Socket clientSocket = null;
    static PrintWriter os = null;
    static BufferedReader is = null;
    static BufferedReader inputLine = null;
    static boolean closed = false;
    static Frame frm;
    static boolean status = false;
    static String username;
    static List<String> user = new ArrayList<String>();
    
    public static void main(String[] args) {
	
    	frm = new Frame();
		Listener();
		
    	// The default port	
	
	int port_number=2222;
        String host="192.168.50.156";
	
	if (args.length < 2)
	    {
		System.out.println("Server: " + host + ", Port: " + port_number);
	    } else {
		host=args[0];
		port_number=Integer.valueOf(args[1]).intValue();
	    }
	// Initialization section:
	// Try to open a socket on a given host and port
	// Try to open input and output streams
	try {
            clientSocket = new Socket(host, port_number);
            //inputLine = new BufferedReader(new InputStreamReader(System.in));
            os = new PrintWriter(clientSocket.getOutputStream());
            is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Kann Host nicht finden: " + host);
        } catch (IOException e) {
            System.err.println("Kann Host nicht erreichen: " + host);
        }
	
	// If everything has been initialized then we want to write some data
	// to the socket we have opened a connection to on port port_number 
	
        if (clientSocket != null && os != null && is != null) {
            try {
            
		
		// Create a thread to read from the server
		
                new Thread(new KopieVonMultiThreadChatClient()).start();
                
		while (!closed) {
                   //os.println(inputLine.readLine());
			if(status == true){
				os.println("#check:"+username);
				try{
					Thread.sleep(4000);
				}catch(Exception e){}
			}
		}
		
		// Clean up:
		// close the output stream
		// close the input stream
		// close the socket
		
		os.close();
		is.close();
		clientSocket.close();   
            } catch (IOException e) {
                System.err.println("IOException:  " + e);
            }
        }
    }           
    
    public void run() {		
	String responseLine;
	
	// Keep on reading from the socket till we receive the "Bye" from the server,
	// once we received that then we want to break.
	try{ 
	    while ((responseLine = is.readLine()) != null) {
	    if(responseLine.contains("#check")) {addInList(responseLine);}
		else{
				//System.out.println(responseLine);
				frm.chatTextArea.append(responseLine+"\n");
		}
		if (responseLine.indexOf("Bye") != -1) {break;}
		if (responseLine.indexOf("offline") != -1) {removeFromList(responseLine);}
	    }
            closed=true;
            try{
            	frm.disconnectButton.setEnabled(false);
            	frm.connectButton.setEnabled(false);
            	frm.sendButton.setEnabled(false);
            	frm.inputTextArea.setEnabled(false);
            	frm.chatTextArea.setEnabled(false);
            	Thread.sleep(2500);
            }catch(Exception e){System.exit(-1);};
            
            System.exit(1);
	} catch (IOException e) {
	    System.err.println("IOException:  " + e);
	}
    }
    
    public void addInList(String input){
    	String[] temp = new String[2];
    	temp = input.split(":");
    	if(user.indexOf(temp[1])==-1)
    	{
    		user.add(temp[1]);
    	}
    	String userString = "";
    	for(String current: user){
    		userString = userString + current + "\n";
    	}
    	frm.usersList.setText(null);
    	frm.usersList.setText(userString);
    }
    
    public void removeFromList(String input){
    	String[] temp = new String[3];
    	temp = input.split("_");
    	if(user.indexOf(temp[1]) != -1)
    	{
    		user.remove(temp[1]);
    	}
    }
    
    public static void Listener() {
    	
    	frm.connectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            os.println(frm.usernameField.getText());
            username = frm.usernameField.getText();
            frm.connectButton.setEnabled(false);
            frm.usernameField.setEnabled(false);
            frm.disconnectButton.setEnabled(true);
            frm.sendButton.setEnabled(true);
            frm.inputTextArea.setEnabled(true);
            frm.inputTextArea.requestFocus();
            frm.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
            status = true;
            }
        });
    	
    	frm.disconnectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	os.println("/quit");
            	os.flush();
            }
        });
    	
    	frm.usernameField.addKeyListener(new KeyListener() {
    	    public void keyPressed(KeyEvent e) {}
    	    public void keyReleased(KeyEvent e) {
    	    	if (e.getKeyCode() == KeyEvent.VK_ENTER) {frm.connectButton.doClick();}
    	    }
    	    public void keyTyped(KeyEvent e) {}
    	});	
    
    	frm.inputTextArea.addKeyListener(new KeyListener() {
    	    public void keyPressed(KeyEvent e) {}
    	    public void keyReleased(KeyEvent e) {
    	    	if (e.getKeyCode() == KeyEvent.VK_ENTER) 
    	    	{
    	    		if(e.isShiftDown()){
    	    			frm.inputTextArea.append("\n");
    	    		}else{
    	    			frm.inputTextArea.setText(frm.inputTextArea.getText().substring(0, frm.inputTextArea.getText().length()-1));
    	    			if(frm.inputTextArea.getText().length()>0){
    	    			frm.sendButton.doClick();}
    	    		}
    	    	}
    	    }
    	    public void keyTyped(KeyEvent e) {}
    	});
    	
    	frm.sendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	os.println(frm.inputTextArea.getText());
            	os.flush();
            	frm.inputTextArea.setText(null);
            }
        });
    	
    }
}

und Server:
Java:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

public class MultiThreadChatServer{

    // Declaration section:
    // declare a server socket and a client socket for the server
    // declare an input and an output stream

    static  Socket clientSocket = null;
    static  ServerSocket serverSocket = null;
    
    // This chat server can accept up to 10 clients' connections

    static  clientThread t[] = new clientThread[10];           
        
    public static void main(String args[]) {
	
	// The default port

	int port_number=2222;
	
	if (args.length < 1)
	    {
		System.out.println("Serverport: " + port_number);
	    } else {
		port_number=Integer.valueOf(args[0]).intValue();
	    }
	
	// Initialization section:
	// Try to open a server socket on port port_number (default 2222)
	// Note that we can't choose a port less than 1023 if we are not
	// privileged users (root)

        try {
	    serverSocket = new ServerSocket(port_number);
        }
        catch (IOException e)
	    {System.out.println(e);}
	
	// Create a socket object from the ServerSocket to listen and accept 
	// connections.
	// Open input and output streams for this socket will be created in 
	// client's thread since every client is served by the server in
	// an individual thread
	
	while(true){
	    try {
		clientSocket = serverSocket.accept();
		for(int i=0; i<=9; i++){
		    if(t[i]==null)
			{
			    (t[i] = new clientThread(clientSocket,t)).start();
			    break;
			}
		}
	    }
	    catch (IOException e) {
		System.out.println(e);}
	}
    }
} 

// This client thread opens the input and the output streams for a particular client,
// ask the client's name, informs all the clients currently connected to the 
// server about the fact that a new client has joined the chat room, 
// and as long as it receive data, echos that data back to all other clients.
// When the client leaves the chat room this thread informs also all the
// clients about that and terminates. 

class clientThread extends Thread{
    
    //DataInputStream is = null;
	BufferedReader is = null;
    //PrintStream os = null;
	PrintWriter os = null;
    Socket clientSocket = null;       
    clientThread t[]; 
    
    
    
    public clientThread(Socket clientSocket, clientThread[] t){
    	
    	
    	this.clientSocket=clientSocket;
        this.t=t;
    }
    
    public void run() 
    {
    	String line;
        String name;
        
	try{
	    //is = new DataInputStream(clientSocket.getInputStream());
		is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
	    //os = new PrintStream(clientSocket.getOutputStream(),true,"utf-8");
		os = new PrintWriter(clientSocket.getOutputStream());
	    //os.println("");
	    name = is.readLine();
	    os.println("Hallo _" + name +"_");
	    os.flush();
	    for(int i=0; i<=9; i++)
		if (t[i]!=null && t[i]!=this) {  
		    t[i].os.println("*** _" + name + "_ ist jetzt online ! ***" );
	    	t[i].os.flush();
		}
	    while (true) {
		line = is.readLine();
                if(line.startsWith("/quit")) break; 
		for(int i=0; i<=9; i++)
		    if (t[i]!=null)  {
		    	t[i].os.println("<"+name+"> "+line);
		    	t[i].os.flush();
		    }
	    }
	    for(int i=0; i<=9; i++)
		if (t[i]!=null && t[i]!=this){  
		    t[i].os.println("*** _" + name + "_ ist jetzt offline ! ***");
		    t[i].os.flush();
		}
	    os.println("*** Bye " + name + " ! ***");
	    os.flush();
	    // Clean up:
	    // Set to null the current thread variable such that other client could
	    // be accepted by the server

	    for(int i=0; i<=9; i++)
		if (t[i]==this) t[i]=null;  
		
	    // close the output stream
	    // close the input stream
	    // close the socket
	    
	    is.close();
	    os.close();
	    clientSocket.close();
	}
	catch(IOException e){};
    }
}


Mein Problem (schwer zu beschreiben):
die clients kommen nicht selbst in gang. sobald ich verbunden bin zeigt er den client noch nicht in der "wer ist online" liste an, die "hallo <benutzername>" (beim neuen client) bzw "<benutzername> ist jetzt online" (bei den clients, die davor online waren) wird nicht gleich angezeigt sondern erst nach dem der neue client seine erste nachricht absendete.
ich sende, in dem ich des PrintWriters Methoden "println()" oder "write()" (dann aber mit flush)" verwende, jedoch erscheinen die zeilen bei den anderen clients dann in einer zeile.
Jedoch soll jede neue nachricht in einer neuen Zeile stehen.
heißt ja "printLINE()"...
kann mir jemand dabei helfen?


bei bedarf lade ich das ganze projekt als ZIP hoch.

Danke schonmal,
euer mac :)
 

Ähnliche Java Themen

Neue Themen


Oben