Hey guys...
So I have probably written the most useless program ever...
This is supposed to be a chat program with multiple clients connecting to one server.
The problem being that the first client connects and can send to the server without problems.
But when you connect two clients, the server doesn't receive anything from the second client until the first client disconnects, but it gets all the messages from the first client... Also, The server doesn't send the message being passed to it to all the rest of the clients.
What I am thinking is that I need a new thread for all clients, but coding it is just taking me forever. Apparently I just fail that hard ^_^
Can anyone please just take a look at it and tell me what to do?
My code for the server:
And now for the client...Code:import java.net.*; import java.io.*; public class myFrame { private static ServerSocket serverSocket; private static Socket clientSocket; private static BufferedReader bufferedReader; private static String inputLine; private Thread thread = null; public static void main(String[] args) { // Wait for client to connect on 63400 try { serverSocket = new ServerSocket(63400); clientSocket = serverSocket.accept(); // Create a reader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // Get the client message while((inputLine = bufferedReader.readLine()) != null) System.out.println(inputLine); } catch(IOException e) { System.out.println(e); } } }
Thank you very much for your timeCode:import java.net.*; import java.io.*; import java.util.*; public class myFrame { private static Socket socket; private static PrintWriter printWriter; public static void main(String[] args) { try { socket = new Socket("localhost",63400); printWriter = new PrintWriter(socket.getOutputStream(),true); String Name; String message = ""; Scanner in = new Scanner(System.in); System.out.println("Please enter your name for the chat."); Name = in.nextLine(); System.out.println("You may now start chatting away!"); while(message.compareTo("exit") != 0) { message = in.nextLine(); printWriter.println(Name + " : " + message); } } catch(Exception e) { System.out.println(e); } } }
^_^
Ok...
I have changed this thing so it can work on a browser using an applet for the client
My server class using Netbeans looks like this:
Then I have another class called ServerThread that looks like this:Code:/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package server; /* * * @author lintwurm */ import java.io.*; import java.net.*; import java.util.*; public class Server { // The ServerSocket we'll use for accepting new connections private ServerSocket ss; // A mapping from sockets to DataOutputStreams. This will // help us avoid having to create a DataOutputStream each time // we want to write to a stream. private Hashtable outputStreams = new Hashtable(); // Constructor and while-accept loop all in one. public Server( int port ) throws IOException { // All we have to do is listen listen( port ); } private void listen( int port ) throws IOException { // Create the ServerSocket ss = new ServerSocket( port ); // Tell the world we're ready to go System.out.println( "Listening on "+ss ); // Keep accepting connections forever while (true) { // Grab the next incoming connection Socket s = ss.accept(); // Tell the world we've got it System.out.println( "Connection from "+s ); // Create a DataOutputStream for writing data to the // other side DataOutputStream dout = new DataOutputStream( s.getOutputStream() ); // Save this stream so we don't need to make it again outputStreams.put( s, dout ); // Create a new thread for this connection, and then forget // about it new ServerThread( this, s ); } } // Get an enumeration of all the OutputStreams, one for each client // connected to us Enumeration getOutputStreams() { return outputStreams.elements(); } // Send a message to all clients (utility routine) void sendToAll( String message ) { // We synchronize on this because another thread might be // calling removeConnection() and this would screw us up // as we tried to walk through the list synchronized( outputStreams ) { // For each client ... for (Enumeration e = getOutputStreams(); e.hasMoreElements(); ) { // ... get the output stream ... DataOutputStream dout = (DataOutputStream)e.nextElement(); // ... and send the message try { dout.writeUTF( message ); } catch( IOException ie ) { System.out.println( ie ); } } } } // Remove a socket, and it's corresponding output stream, from our // list. This is usually called by a connection thread that has // discovered that the connectin to the client is dead. void removeConnection( Socket s ) { // Synchronize so we don't mess up sendToAll() while it walks // down the list of all output streamsa synchronized( outputStreams ) { // Tell the world System.out.println( "Removing connection to "+s ); // Remove it from our hashtable/list outputStreams.remove( s ); // Make sure it's closed try { s.close(); } catch( IOException ie ) { System.out.println( "Error closing "+s ); ie.printStackTrace(); } } } // Main routine // Usage: java Server <port> static public void main( String args[] ) throws Exception { // Get the port # from the command line int port = 80; // Create a Server object, which will automatically begin // accepting connections. new Server( port ); } }
Now for the client...Code:/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package server; /* * * @author s28339208 */ import java.io.*; import java.net.*; public class ServerThread extends Thread { // The Server that spawned us private Server server; // The Socket connected to our client private Socket socket; // Constructor. public ServerThread( Server server, Socket socket ) { // Save the parameters this.server = server; this.socket = socket; // Start up the thread start(); } // This runs in a separate thread when start() is called in the // constructor. public void run() { try { // Create a DataInputStream for communication; the client // is using a DataOutputStream to write to us DataInputStream din = new DataInputStream( socket.getInputStream() ); // Over and over, forever ... while (true) { // ... read the next message ... String message = din.readUTF(); // ... tell the world ... System.out.println( "Sending "+message ); // ... and have the server send it to all clients server.sendToAll( message ); } } catch( EOFException ie ) { // This doesn't need an error message } catch( IOException ie ) { // This does; tell the world! ie.printStackTrace(); } finally { // The connection is closed for one reason or another, // so have the server dealing with it server.removeConnection( socket ); } } }
And the applet part.Code:/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package client; /* * * @author s28339208 */ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Client extends Panel implements Runnable { // Components for the visual display of the chat windows private TextField tf = new TextField(); private TextArea ta = new TextArea(); // The socket connecting us to the server private Socket socket; // The streams we communicate to the server; these come // from the socket private DataOutputStream dout; private DataInputStream din; // Constructor public Client( String host, int port ) { // Set up the screen setLayout( new BorderLayout() ); add( "North", tf ); add( "Center", ta ); // We want to receive messages when someone types a line // and hits return, using an anonymous class as // a callback tf.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { processMessage( e.getActionCommand() ); } } ); // Connect to the server try { // Initiate the connection socket = new Socket( "localhost", 80 ); // We got a connection! Tell the world System.out.println( "connected to "+socket ); // Let's grab the streams and create DataInput/Output streams // from them din = new DataInputStream( socket.getInputStream() ); dout = new DataOutputStream( socket.getOutputStream() ); // Start a background thread for receiving messages new Thread( this ).start(); } catch( IOException ie ) { System.out.println( ie ); } } // Gets called when the user types something private void processMessage( String message ) { try { // Send it to the server dout.writeUTF( message ); // Clear out text input field tf.setText( "" ); } catch( IOException ie ) { System.out.println( ie ); } } // Background thread runs this: show messages from other window public void run() { try { // Receive messages one-by-one, forever while (true) { // Get the next message String message = din.readUTF(); // Print it to our text window ta.append( message+"\n" ); } } catch( IOException ie ) { System.out.println( ie ); } } }
now for the stupid part...Code:/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package client; /* * * @author s28339208 */ import java.applet.*; import java.awt.*; public class ClientApplet extends Applet { public void init() { String host = getParameter( "localhost" ); int port = 80; setLayout( new BorderLayout() ); add( "Center", new Client( host, port ) ); } }
I created a html file that calls the ClientApplet.class (as I think I should)
but the browser just says that it has an error instead of displaying the applet. Am I being stupid and calling the wrong class?
This is the exact output I get from the browser:
And one more question,Code:java.lang.NoClassDefFoundError: ClientApplet (wrong name: client/ClientApplet) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source) at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Exception: java.lang.NoClassDefFoundError: ClientApplet (wrong name: client/ClientApplet)
Will this work if I run the server from Netbeans and the clients just html? Or is this why the browser is complaining?
Thank you for your time
^_^
Last edited by lintwurm; 03-25-2010 at 12:14 PM. Reason: added the error output from the browser
You Just need to use a single thread for each client because obviously you cant ask the server to handle more than 1 client at a time without multi-tasking. The server should create a clientThread whenever it has a new connection.
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks