Java Instant Messenger - Connecting multiple clients to server and oneanother -
i have written simple client/server instant messaging program, has basic functionality.
as stands, can send/receive messages between server , 1 connected client. however, subsequent clients not connect server.
i wish implement features allow following:
successful connection of 2+ clients server;
multiple clients connecting server , communicating each other , server.
i think need setup new thread each connection, i'm unsure how go this.
please advise (see code below).
any appreciated.
many thanks.
client.java:
import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import java.util.date; //timestamp functionality import javax.swing.*; public class client extends jframe { //inherits jframe //1. creating instance variables private jtextfield usertext; //where user inputs text private jtextarea chatwindow; //where messages displayed private string fulltimestamp = new java.text.simpledateformat("dd/mm/yyyy hh:mm:ss").format(new date()); //fulltimestamp - mm = months; mm = minutes; hh = 24-hour cloc private objectoutputstream output; //output client server private objectinputstream input; //messages received server private string message =""; private string serverip; private socket connection; //2. constructor (gui) public client(string host){ //host=ip address of server super("mick's instant messenger [client]"); serverip = host; //placed here allow access private string serverip usertext = new jtextfield(); usertext.seteditable(false); usertext.addactionlistener( new actionlistener(){ public void actionperformed(actionevent event){ sendmessage(event.getactioncommand()); //for work, must build senddata method usertext.settext(""); //resets usertext blank, after message has been sent allow new message(s) } } ); add(usertext, borderlayout.south); chatwindow = new jtextarea(); add(new jscrollpane(chatwindow), borderlayout.center); //allows scroll , down when text outgrows chatwindow chatwindow.setlinewrap(true); //wraps lines when outgrow panel width chatwindow.setwrapstyleword(true); //ensures above line wrap occurs @ word end setsize(400,320); this.setlocationrelativeto(null); //places frame in center of screen setvisible(true); } //3. startrunning method public void startrunning(){ try{ connecttoserver(); //unlike server, no need wait connections. connects 1 specific server. setupstreams(); whilechatting(); }catch(eofexception eofexception){ //display timestamp disconnection showmessage("\n\n" + fulltimestamp); showmessage("\nconnection terminated client! "); }catch(ioexception ioexception){ ioexception.printstacktrace(); }finally{ closecrap(); } } //4. connect server void connecttoserver() throws ioexception{ showmessage(" \n attempting connection server... \n"); connection = new socket(inetaddress.getbyname(serverip), 6789);//server ip can added later showmessage(" connected to: " +connection.getinetaddress().gethostname() ); //displays ip address of server } //5. setup streams send , receive messages private void setupstreams() throws ioexception{ output = new objectoutputstream(connection.getoutputstream()); output.flush(); input = new objectinputstream(connection.getinputstream()); showmessage("\n streams setup! \n"); } //6. while chatting method private void whilechatting() throws ioexception{ //display timestamp connection showmessage("\n" + fulltimestamp); abletotype(true); string timestamp = new java.text.simpledateformat("hh:mm:ss").format(new date());//timestamp do{ try{ message = (string) input.readobject(); //read input, treat string, store in message variable showmessage("\n" + message); }catch(classnotfoundexception classnotfoundexception){ showmessage("\n don't know object type"); } //***broken timestamp?*** }while(!message.equalsignorecase("server " + "[" + timestamp + "]" + ": " + "end")); //conversation happens until server inputs 'end' } //7. close streams , sockets private void closecrap(){ showmessage("\n\nclosing streams , sockets..."); abletotype(false);//disable typing feature when closing streams , sockets try{ output.close(); input.close(); connection.close(); }catch(ioexception ioexception){ ioexception.printstacktrace(); //show error messages or exceptions } } //8. send messages server private void sendmessage(string message){ try{ string timestamp = new java.text.simpledateformat("hh:mm:ss").format(new date());//timestamp output.writeobject("client" + " [" + timestamp + "]" + ": " + message); output.flush(); showmessage("\nclient" + " [" + timestamp + "]" + ": " + message); }catch(ioexception ioexception){ chatwindow.append("\n error: message not sent!"); } } //9.change/update chatwindow private void showmessage(final string m){ swingutilities.invokelater( new runnable(){ public void run(){ chatwindow.seteditable(false); //disallows text editing in chatwindow chatwindow.append(m); //appends text, passed in above } } ); } //10. lets user type private void abletotype(final boolean tof){ swingutilities.invokelater( new runnable(){ public void run(){ usertext.seteditable(tof); //passes in 'true' } } ); } }
server.java:
import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.date;//timestamp functionality public class server extends jframe{ //inherits jframe //1. instance variables private jtextfield usertext; //where messages typed private jtextarea chatwindow; //where messages displayed private string fulltimestamp = new java.text.simpledateformat("dd/mm/yyyy hh:mm:ss").format(new date()); //fulltimestamp - mm = months; mm = minutes; hh = 24-hour clock //setting streams private objectoutputstream output; //messages being sent user private objectinputstream input; //messages being received user; private serversocket server; private socket connection; //socket = sets connection between 1 computer , another. //2. constructor (gui) public server(){ super("mick's instant messenger [server]"); //window title usertext = new jtextfield(); usertext.seteditable(false); //you cannot type anything, unless connected else usertext.addactionlistener( new actionlistener(){ public void actionperformed(actionevent event){ sendmessage(event.getactioncommand()); usertext.settext(""); //resets editable text field after send message } } ); add(usertext, borderlayout.south);//places user text input (jtextarea) field @ bottom chatwindow = new jtextarea(15,30); //displays conversation add(new jscrollpane(chatwindow)); chatwindow.setlinewrap(true); //wraps lines when outgrow panel width chatwindow.setwrapstyleword(true); //ensures above line wrap occurs @ word end setsize(400,320); this.setlocationrelativeto(null); //places frame in center of screen setvisible(true); //set visible on screen } //3.setup , run server public void startrunning(){ try{ server = new serversocket(6789, 100); //client connects @ port # 6789 //100 = queuelength - backlog of clients can wait @ port #6789 connect server //while(true) ... means while loop going run forever while(true){ try{ waitforconnection(); setupstreams(); whilechatting(); //allows messages pass , forth through streams }catch(eofexception eofexception){ //connect , have conversation //display timestamp disconnection showmessage("\n\n" + fulltimestamp); showmessage("\nconnection terminated server! "); //displays end of stream/connection }finally{ closecrap(); } } }catch(ioexception ioexception){ ioexception.printstacktrace(); //displays info there's error! } } //4. wait connection method, display connection info private void waitforconnection() throws ioexception{ showmessage("\n server : waiting user(s) connect... \n "); //tells user server waiting connection connection = server.accept(); //socket "connection" accept connections. creates socket each new connection. showmessage("connected " +connection.getinetaddress().gethostname()); //displays ip address , hostname } //5. setup streams method.. streams send , receive data private void setupstreams() throws ioexception{ output = new objectoutputstream(connection.getoutputstream()); //creates pathway allow connection whichever computer 'connnection' socket created. output.flush(); //clears data gets left on in buffer when try connect else. flushes on other person. input = new objectinputstream(connection.getinputstream()); //no flush here, because cannot flush else's stream showmessage("\n streams setup! \n"); } //6. during conversation method private void whilechatting() throws ioexception{ //display timestamp connection showmessage("\n" + fulltimestamp); string message = "you connected! \n "; sendmessage(message); abletotype(true); //will allow user type text box after connection string timestamp = new java.text.simpledateformat("hh:mm:ss").format(new date());//timestamp do{ try{ message = (string) input.readobject(); //read incoming message string , store in 'message' variable. showmessage("\n" + message);//displays each message receive on new line }catch(classnotfoundexception classnotfoundexception){ showmessage("/n don't know object user has sent!"); } //***broken timestamp?*** }while(!message.equalsignorecase("client " + "[" + timestamp + "]" + ": " + "end")); //allows conversation until client enters "end" } //7. close crap method - close streams , sockets after finished chatting private void closecrap(){ showmessage("\n\n closing connections... \n"); abletotype(false); try{ output.close(); //close stream other users input.close(); //close incoming streams connection.close(); //close socket }catch(ioexception ioexception){ ioexception.printstacktrace(); } } //8. send message method - send message client private void sendmessage(string message){ try{ //writeobject method built java. string timestamp = new java.text.simpledateformat("hh:mm:ss").format(new date());//timestamp output.writeobject("server" + " [" + timestamp + "]" + ": " + message); showmessage("\nserver" + " [" + timestamp + "]" + ": " + message); //shows ouput message in our conversation window output.flush(); }catch(ioexception ioexception){ chatwindow.append("error: unable send message!"); } } //9. updates chatwindow - instead of creating entirely new gui each time private void showmessage(final string text){ swingutilities.invokelater( new runnable(){ public void run(){ chatwindow.seteditable(false); //disallows text editing in chatwindow chatwindow.append(text); //appends text, passed in above } } ); } //10. lets user type private void abletotype(final boolean tof){ swingutilities.invokelater( new runnable(){ public void run(){ usertext.seteditable(tof); //passes in 'true' } } ); } }
the way serversockets work in java clients want connect queued until can serversocket.accept()
dequeues first 1 , returns it. therefore, multiple clients connected single server, need call accept multiple times. accept block until client available, may know.
you need create connection handler thread handles single client connection, , spawn threads off whenever new client connected. basically
while(true){ socket s=server.accept(); new connectionhandlerthread(s).start(); // write connectionhandlerthread }
i write more detailed code you, i'm on mobile sorry.
Comments
Post a Comment