Java Socket Programming Examples
Java Socket Programming Examples
Programming
Examples
Although most programmers probably do network programming using a nice library
with high-level application protocol (such as HTTP) support built-in, it's still useful to
have an understanding of how to code at the socket level. Here are a few complete
examples you can compile and run.
Overview
We will look at four network applications, written completely from scratch in
Java. We will see that we can write these programs without any knowledge
of the technologies under the hood (which include operating system
resources, routing between networks, address lookup, physical
transmission media, etc.)
Each of these applications use the client-server paradigm, which is roughly
1. One program, called the server blocks waiting for a client to connect
to it
2. A client connects
3. The server and the client exchange information until they're done
4. The client and the server both close their connection
The only pieces of background information you need are:
importjava.net.ServerSocket;
importjava.net.Socket;
importjava.util.Date;
/**
*ATCPserverthatrunsonport9090.Whenaclient
connects,it
*sendstheclientthecurrentdateandtime,thenclosesthe
*connectionwiththatclient.Arguablyjustaboutthe
simplest
*serveryoucanwrite.
*/
publicclassDateServer{
/**
*Runstheserver.
*/
publicstaticvoidmain(String[]args)throwsIOException
{
ServerSocketlistener=newServerSocket(9090);
try{
while(true){
Socketsocket=listener.accept();
try{
PrintWriterout=
new
PrintWriter(socket.getOutputStream(),true);
out.println(newDate().toString());
}finally{
socket.close();
}
}
}
finally{
listener.close();
}
}
}
The client
DateClient.java
packageedu.lmu.cs.networking;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.Socket;
importjavax.swing.JOptionPane;
/**
*Trivialclientforthedateserver.
*/
publicclassDateClient{
/**
*Runstheclientasanapplication.Firstitdisplaysa
dialog
*boxaskingfortheIPaddressorhostnameofahost
running
*thedateserver,thenconnectstoitanddisplaysthe
datethat
*itserves.
*/
publicstaticvoidmain(String[]args)throwsIOException
{
StringserverAddress=JOptionPane.showInputDialog(
"EnterIPAddressofamachinethatis\n"+
"runningthedateserviceonport9090:");
Sockets=newSocket(serverAddress,9090);
BufferedReaderinput=
newBufferedReader(new
InputStreamReader(s.getInputStream()));
Stringanswer=input.readLine();
JOptionPane.showMessageDialog(null,answer);
System.exit(0);
}
}
*spawnsanewthreadtodotheservicingandimmediately
returns
*tolistening.Theserverkeepsauniqueclientnumber
foreach
*clientthatconnectsjusttoshowinterestinglogging
*messages.Itiscertainlynotnecessarytodothis.
*/
publicstaticvoidmain(String[]args)throwsException{
System.out.println("Thecapitalizationserveris
running.");
intclientNumber=0;
ServerSocketlistener=newServerSocket(9898);
try{
while(true){
newCapitalizer(listener.accept(),
clientNumber++).start();
}
}finally{
listener.close();
}
}
/**
*Aprivatethreadtohandlecapitalizationrequestsona
particular
*socket.Theclientterminatesthedialoguebysending
asingleline
*containingonlyaperiod.
*/
privatestaticclassCapitalizerextendsThread{
privateSocketsocket;
privateintclientNumber;
publicCapitalizer(Socketsocket,intclientNumber){
this.socket=socket;
this.clientNumber=clientNumber;
log("Newconnectionwithclient#"+clientNumber
+"at"+socket);
}
/**
*Servicesthisthread'sclientbyfirstsendingthe
*clientawelcomemessagethenrepeatedlyreading
strings
*andsendingbackthecapitalizedversionofthe
string.
*/
publicvoidrun(){
try{
//Decoratethestreamssowecansend
characters
//andnotjustbytes.Ensureoutputis
flushed
//aftereverynewline.
BufferedReaderin=newBufferedReader(
new
InputStreamReader(socket.getInputStream()));
PrintWriterout=
newPrintWriter(socket.getOutputStream(),
true);
//Sendawelcomemessagetotheclient.
out.println("Hello,youareclient#"+
clientNumber+".");
out.println("Enteralinewithonlyaperiod
toquit\n");
//Getmessagesfromtheclient,linebyline;
returnthem
//capitalized
while(true){
Stringinput=in.readLine();
if(input==null||input.equals(".")){
break;
}
out.println(input.toUpperCase());
}
}catch(IOExceptione){
log("Errorhandlingclient#"+clientNumber+
":"+e);
}finally{
try{
socket.close();
}catch(IOExceptione){
log("Couldn'tcloseasocket,what'sgoing
on?");
}
log("Connectionwithclient#"+clientNumber
+"closed");
}
}
/**
*Logsasimplemessage.Inthiscasewejustwrite
the
*messagetotheserverapplicationsstandardoutput.
*/
privatevoidlog(Stringmessage){
System.out.println(message);
}
}
}
The client
CapitalizeClient.java
packageedu.lmu.cs.networking;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.Socket;
importjavax.swing.JFrame;
importjavax.swing.JOptionPane;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
importjavax.swing.JTextField;
/**
*AsimpleSwingbasedclientforthecapitalizationserver.
*Ithasamainframewindowwithatextfieldforentering
*stringsandatextareatoseetheresultsofcapitalizing
*them.
*/
publicclassCapitalizeClient{
privateBufferedReaderin;
privatePrintWriterout;
privateJFrameframe=newJFrame("CapitalizeClient");
privateJTextFielddataField=newJTextField(40);
privateJTextAreamessageArea=newJTextArea(8,60);
/**
*ConstructstheclientbylayingouttheGUIand
registeringa
*listenerwiththetextfieldsothatpressingEnterin
the
*listenersendsthetextfieldcontentstotheserver.
*/
publicCapitalizeClient(){
//LayoutGUI
messageArea.setEditable(false);
frame.getContentPane().add(dataField,"North");
frame.getContentPane().add(new
JScrollPane(messageArea),"Center");
//AddListeners
dataField.addActionListener(newActionListener(){
/**
*Respondstopressingtheenterkeyinthe
textfield
*bysendingthecontentsofthetextfieldto
the
*serveranddisplayingtheresponsefromthe
server
*inthetextarea.Iftheresponseis"."we
exit
*thewholeapplication,whichclosesall
sockets,
*streamsandwindows.
*/
publicvoidactionPerformed(ActionEvente){
out.println(dataField.getText());
Stringresponse;
try{
response=in.readLine();
if(response==null||
response.equals("")){
System.exit(0);
}
}catch(IOExceptionex){
response="Error:"+ex;
}
messageArea.append(response+"\n");
dataField.selectAll();
}
});
}
/**
*Implementstheconnectionlogicbypromptingtheend
userfor
*theserver'sIPaddress,connecting,settingup
streams,and
*consumingthewelcomemessagesfromtheserver.The
Capitalizer
*protocolsaysthattheserversendsthreelinesoftext
tothe
*clientimmediatelyafterestablishingaconnection.
*/
publicvoidconnectToServer()throwsIOException{
//Gettheserveraddressfromadialogbox.
StringserverAddress=JOptionPane.showInputDialog(
frame,
"EnterIPAddressoftheServer:",
"WelcometotheCapitalizationProgram",
JOptionPane.QUESTION_MESSAGE);
//Makeconnectionandinitializestreams
Socketsocket=newSocket(serverAddress,9898);
in=newBufferedReader(
new
InputStreamReader(socket.getInputStream()));
out=newPrintWriter(socket.getOutputStream(),true);
//Consumetheinitialwelcomingmessagesfromthe
server
for(inti=0;i<3;i++){
messageArea.append(in.readLine()+"\n");
}
}
/**
*Runstheclientapplication.
*/
publicstaticvoidmain(String[]args)throwsException{
CapitalizeClientclient=newCapitalizeClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.pack();
client.frame.setVisible(true);
client.connectToServer();
}
}
TicTacToeServer.java
packageedu.lmu.cs.networking;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
/**
*Aserverforanetworkmultiplayertictactoegame.
Modifiedand
*extendedfromtheclasspresentedinDeitelandDeitel
"JavaHowto
*Program"book.Imadeabunchofenhancementsandrewrote
largesections
*ofthecode.Themainchangeisinsteadofpassing*data*
betweenthe
*clientandserver,ImadeaTTTP(tictactoeprotocol)
whichistotally
*plaintext,soyoucantestthegamewithTelnet(alwaysa
goodidea.)
*ThestringsthataresentinTTTPare:
*
*Client>ServerServer>Client
*
*MOVE<n>(0<=n<=8)WELCOME<char>(charin{X,
O})
*QUITVALID_MOVE
*OTHER_PLAYER_MOVED<n>
*VICTORY
*DEFEAT
*TIE
*MESSAGE<text>
*
*Asecondchangeisthatitallowsanunlimitednumberof
pairsof
*playerstoplay.
*/
publicclassTicTacToeServer{
/**
*Runstheapplication.Pairsupclientsthatconnect.
*/
publicstaticvoidmain(String[]args)throwsException{
ServerSocketlistener=newServerSocket(8901);
System.out.println("TicTacToeServerisRunning");
try{
while(true){
Gamegame=newGame();
Game.PlayerplayerX=game.new
Player(listener.accept(),'X');
Game.PlayerplayerO=game.new
Player(listener.accept(),'O');
playerX.setOpponent(playerO);
playerO.setOpponent(playerX);
game.currentPlayer=playerX;
playerX.start();
playerO.start();
}
}finally{
listener.close();
}
}
}
/**
*Atwoplayergame.
*/
classGame{
/**
*Aboardhasninesquares.Eachsquareiseither
unownedor
*itisownedbyaplayer.Soweuseasimplearrayof
player
*references.Ifnull,thecorrespondingsquareis
unowned,
*otherwisethearraycellstoresareferencetothe
playerthat
*ownsit.
*/
privatePlayer[]board={
null,null,null,
null,null,null,
null,null,null};
/**
*Thecurrentplayer.
*/
PlayercurrentPlayer;
/**
*Returnswhetherthecurrentstateoftheboardissuch
thatone
*oftheplayersisawinner.
*/
publicbooleanhasWinner(){
return
(board[0]!=null&&board[0]==board[1]&&
board[0]==board[2])
||(board[3]!=null&&board[3]==board[4]&&
board[3]==board[5])
||(board[6]!=null&&board[6]==board[7]&&
board[6]==board[8])
||(board[0]!=null&&board[0]==board[3]&&
board[0]==board[6])
||(board[1]!=null&&board[1]==board[4]&&
board[1]==board[7])
||(board[2]!=null&&board[2]==board[5]&&
board[2]==board[8])
||(board[0]!=null&&board[0]==board[4]&&
board[0]==board[8])
||(board[2]!=null&&board[2]==board[4]&&
board[2]==board[6]);
}
/**
*Returnswhethertherearenomoreemptysquares.
*/
publicbooleanboardFilledUp(){
for(inti=0;i<board.length;i++){
if(board[i]==null){
returnfalse;
}
}
returntrue;
}
/**
*Calledbytheplayerthreadswhenaplayertriesto
makea
*move.Thismethodcheckstoseeifthemoveislegal:
that
*is,theplayerrequestingthemovemustbethecurrent
player
*andthesquareinwhichsheistryingtomovemustnot
already
*beoccupied.Ifthemoveislegalthegamestateis
updated
*(thesquareissetandthenextplayerbecomescurrent)
and
*theotherplayerisnotifiedofthemovesoitcan
updateits
*client.
*/
publicsynchronizedbooleanlegalMove(intlocation,Player
player){
if(player==currentPlayer&&board[location]==
null){
board[location]=currentPlayer;
currentPlayer=currentPlayer.opponent;
currentPlayer.otherPlayerMoved(location);
returntrue;
}
returnfalse;
}
/**
*Theclassforthehelperthreadsinthismultithreaded
server
*application.APlayerisidentifiedbyacharacter
mark
*whichiseither'X'or'O'.Forcommunicationwiththe
*clienttheplayerhasasocketwithitsinputand
output
*streams.Sinceonlytextisbeingcommunicatedweuse
a
*readerandawriter.
*/
classPlayerextendsThread{
charmark;
Playeropponent;
Socketsocket;
BufferedReaderinput;
PrintWriteroutput;
/**
*Constructsahandlerthreadforagivensocketand
mark
*initializesthestreamfields,displaysthefirst
two
*welcomingmessages.
*/
publicPlayer(Socketsocket,charmark){
this.socket=socket;
this.mark=mark;
try{
input=newBufferedReader(
new
InputStreamReader(socket.getInputStream()));
output=new
PrintWriter(socket.getOutputStream(),true);
output.println("WELCOME"+mark);
output.println("MESSAGEWaitingforopponent
toconnect");
}catch(IOExceptione){
System.out.println("Playerdied:"+e);
}
}
/**
*Acceptsnotificationofwhotheopponentis.
*/
publicvoidsetOpponent(Playeropponent){
this.opponent=opponent;
}
/**
*HandlestheotherPlayerMovedmessage.
*/
publicvoidotherPlayerMoved(intlocation){
output.println("OPPONENT_MOVED"+location);
output.println(
hasWinner()?"DEFEAT":boardFilledUp()?
"TIE":"");
}
/**
*Therunmethodofthisthread.
*/
publicvoidrun(){
try{
//Thethreadisonlystartedaftereveryone
connects.
output.println("MESSAGEAllplayers
connected");
//Tellthefirstplayerthatitisherturn.
if(mark=='X'){
output.println("MESSAGEYourmove");
}
//Repeatedlygetcommandsfromtheclientand
processthem.
while(true){
Stringcommand=input.readLine();
if(command.startsWith("MOVE")){
intlocation=
Integer.parseInt(command.substring(5));
if(legalMove(location,this)){
output.println("VALID_MOVE");
output.println(hasWinner()?
"VICTORY"
:boardFilledUp()?
"TIE"
:"");
}else{
output.println("MESSAGE?");
}
}elseif(command.startsWith("QUIT")){
return;
}
}
}catch(IOExceptione){
System.out.println("Playerdied:"+e);
}finally{
try{socket.close();}catch(IOExceptione){}
}
}
}
}
The client
TicTacToeClient.java
packageedu.lmu.cs.networking;
importjava.awt.Color;
importjava.awt.GridLayout;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.Socket;
importjavax.swing.Icon;
importjavax.swing.ImageIcon;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JPanel;
/**
*AclientfortheTicTacToegame,modifiedandextendedfrom
the
*classpresentedinDeitelandDeitel"JavaHowtoProgram"
book.
*Imadeabunchofenhancementsandrewrotelargesections
ofthe
*code.InparticularIcreatedtheTTTP(TicTacToe
Protocol)
*whichisentirelytextbased.Herearethestringsthat
aresent:
*
*Client>ServerServer>Client
*
*MOVE<n>(0<=n<=8)WELCOME<char>(charin{X,
O})
*QUITVALID_MOVE
*OTHER_PLAYER_MOVED<n>
*VICTORY
*DEFEAT
*TIE
*MESSAGE<text>
*
*/
publicclassTicTacToeClient{
privateJFrameframe=newJFrame("TicTacToe");
privateJLabelmessageLabel=newJLabel("");
privateImageIconicon;
privateImageIconopponentIcon;
privateSquare[]board=newSquare[9];
privateSquarecurrentSquare;
privatestaticintPORT=8901;
privateSocketsocket;
privateBufferedReaderin;
privatePrintWriterout;
/**
*Constructstheclientbyconnectingtoaserver,laying
outthe
*GUIandregisteringGUIlisteners.
*/
publicTicTacToeClient(StringserverAddress)throws
Exception{
//Setupnetworking
socket=newSocket(serverAddress,PORT);
in=newBufferedReader(newInputStreamReader(
socket.getInputStream()));
out=newPrintWriter(socket.getOutputStream(),true);
//LayoutGUI
messageLabel.setBackground(Color.lightGray);
frame.getContentPane().add(messageLabel,"South");
JPanelboardPanel=newJPanel();
boardPanel.setBackground(Color.black);
boardPanel.setLayout(newGridLayout(3,3,2,2));
for(inti=0;i<board.length;i++){
finalintj=i;
board[i]=newSquare();
board[i].addMouseListener(newMouseAdapter(){
publicvoidmousePressed(MouseEvente){
currentSquare=board[j];
out.println("MOVE"+j);}});
boardPanel.add(board[i]);
}
frame.getContentPane().add(boardPanel,"Center");
}
/**
*Themainthreadoftheclientwilllistenformessages
*fromtheserver.Thefirstmessagewillbea"WELCOME"
*messageinwhichwereceiveourmark.Thenwegointo
a
*looplisteningfor"VALID_MOVE","OPPONENT_MOVED",
"VICTORY",
*"DEFEAT","TIE","OPPONENT_QUITor"MESSAGE"messages,
*andhandlingeachmessageappropriately.The
"VICTORY",
*"DEFEAT"and"TIE"asktheuserwhetherornottoplay
*anothergame.Iftheanswerisno,theloopisexited
and
*theserverissenta"QUIT"message.Ifan
OPPONENT_QUIT
*messageisreceviedthentheloopwillexitandthe
server
*willbesenta"QUIT"messagealso.
*/
publicvoidplay()throwsException{
Stringresponse;
try{
response=in.readLine();
if(response.startsWith("WELCOME")){
charmark=response.charAt(8);
icon=newImageIcon(mark=='X'?"x.gif":
"o.gif");
opponentIcon=newImageIcon(mark=='X'?
"o.gif":"x.gif");
frame.setTitle("TicTacToePlayer"+
mark);
}
while(true){
response=in.readLine();
if(response.startsWith("VALID_MOVE")){
messageLabel.setText("Validmove,please
wait");
currentSquare.setIcon(icon);
currentSquare.repaint();
}elseif
(response.startsWith("OPPONENT_MOVED")){
intloc=
Integer.parseInt(response.substring(15));
board[loc].setIcon(opponentIcon);
board[loc].repaint();
messageLabel.setText("Opponentmoved,your
turn");
}elseif(response.startsWith("VICTORY")){
messageLabel.setText("Youwin");
break;
}elseif(response.startsWith("DEFEAT")){
messageLabel.setText("Youlose");
break;
}elseif(response.startsWith("TIE")){
messageLabel.setText("Youtied");
break;
}elseif(response.startsWith("MESSAGE")){
messageLabel.setText(response.substring(8));
}
}
out.println("QUIT");
}
finally{
socket.close();
}
}
privatebooleanwantsToPlayAgain(){
intresponse=JOptionPane.showConfirmDialog(frame,
"Wanttoplayagain?",
"TicTacToeisFunFunFun",
JOptionPane.YES_NO_OPTION);
frame.dispose();
returnresponse==JOptionPane.YES_OPTION;
}
/**
*Graphicalsquareintheclientwindow.Eachsquareis
*awhitepanelcontaining.AclientcallssetIcon()to
fill
*itwithanIcon,presumablyanXorO.
*/
staticclassSquareextendsJPanel{
JLabellabel=newJLabel((Icon)null);
publicSquare(){
setBackground(Color.white);
add(label);
}
publicvoidsetIcon(Iconicon){
label.setIcon(icon);
}
}
/**
*Runstheclientasanapplication.
*/
publicstaticvoidmain(String[]args)throwsException{
while(true){
StringserverAddress=(args.length==0)?
"localhost":args[1];
TicTacToeClientclient=new
TicTacToeClient(serverAddress);
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setSize(240,160);
client.frame.setVisible(true);
client.frame.setResizable(false);
client.play();
if(!client.wantsToPlayAgain()){
break;
}
}
}
}
The server
ChatServer.java
packageedu.lmu.cs.networking;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
importjava.util.HashSet;
/**
*Amultithreadedchatroomserver.Whenaclientconnects
the
*serverrequestsascreennamebysendingtheclientthe
*text"SUBMITNAME",andkeepsrequestinganameuntil
*auniqueoneisreceived.Afteraclientsubmitsaunique
*name,theserveracknowledgeswith"NAMEACCEPTED".Then
*allmessagesfromthatclientwillbebroadcasttoall
other
*clientsthathavesubmittedauniquescreenname.The
*broadcastmessagesareprefixedwith"MESSAGE".
*
*Becausethisisjustateachingexampletoillustratea
simple
*chatserver,thereareafewfeaturesthathavebeenleft
out.
*Twoareveryusefulandbelonginproductioncode:
*
*1.Theprotocolshouldbeenhancedsothattheclient
can
*sendcleandisconnectmessagestotheserver.
*
*2.Theservershoulddosomelogging.
*/
publicclassChatServer{
/**
*Theportthattheserverlistenson.
*/
privatestaticfinalintPORT=9001;
/**
*Thesetofallnamesofclientsinthechatroom.
Maintained
*sothatwecancheckthatnewclientsarenot
registeringname
*alreadyinuse.
*/
privatestaticHashSet<String>names=new
HashSet<String>();
/**
*Thesetofalltheprintwritersforalltheclients.
This
*setiskeptsowecaneasilybroadcastmessages.
*/
privatestaticHashSet<PrintWriter>writers=new
HashSet<PrintWriter>();
/**
*Theappplicationmainmethod,whichjustlistensona
portand
*spawnshandlerthreads.
*/
publicstaticvoidmain(String[]args)throwsException{
System.out.println("Thechatserverisrunning.");
ServerSocketlistener=newServerSocket(PORT);
try{
while(true){
newHandler(listener.accept()).start();
}
}finally{
listener.close();
}
}
/**
*Ahandlerthreadclass.Handlersarespawnedfromthe
listening
*loopandareresponsibleforadealingwithasingle
client
*andbroadcastingitsmessages.
*/
privatestaticclassHandlerextendsThread{
privateStringname;
privateSocketsocket;
privateBufferedReaderin;
privatePrintWriterout;
/**
*Constructsahandlerthread,squirrelingawaythe
socket.
*Alltheinterestingworkisdoneintherunmethod.
*/
publicHandler(Socketsocket){
this.socket=socket;
}
/**
*Servicesthisthread'sclientbyrepeatedly
requestinga
*screennameuntilauniqueonehasbeensubmitted,
then
*acknowledgesthenameandregisterstheoutput
streamfor
*theclientinaglobalset,thenrepeatedlygets
inputsand
*broadcaststhem.
*/
publicvoidrun(){
try{
//Createcharacterstreamsforthesocket.
in=newBufferedReader(newInputStreamReader(
socket.getInputStream()));
out=new
PrintWriter(socket.getOutputStream(),true);
//Requestanamefromthisclient.Keep
requestinguntil
//anameissubmittedthatisnotalready
used.Notethat
//checkingfortheexistenceofanameand
addingthename
//mustbedonewhilelockingthesetof
names.
while(true){
out.println("SUBMITNAME");
name=in.readLine();
if(name==null){
return;
}
synchronized(names){
if(!names.contains(name)){
names.add(name);
break;
}
}
}
//Nowthatasuccessfulnamehasbeenchosen,
addthe
//socket'sprintwritertothesetofall
writersso
//thisclientcanreceivebroadcastmessages.
out.println("NAMEACCEPTED");
writers.add(out);
//Acceptmessagesfromthisclientand
broadcastthem.
//Ignoreotherclientsthatcannotbe
broadcastedto.
while(true){
Stringinput=in.readLine();
if(input==null){
return;
}
for(PrintWriterwriter:writers){
writer.println("MESSAGE"+name+":
"+input);
}
}
}catch(IOExceptione){
System.out.println(e);
}finally{
//Thisclientisgoingdown!Removeitsname
anditsprint
//writerfromthesets,andcloseitssocket.
if(name!=null){
names.remove(name);
}
if(out!=null){
writers.remove(out);
}
try{
socket.close();
}catch(IOExceptione){
}
}
}
}
}
The client
ChatClient.java
packageedu.lmu.cs.networking;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.Socket;
importjavax.swing.JFrame;
importjavax.swing.JOptionPane;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
importjavax.swing.JTextField;
/**
*AsimpleSwingbasedclientforthechatserver.
Graphically
*itisaframewithatextfieldforenteringmessagesanda
*textareatoseethewholedialog.
*
*TheclientfollowstheChatProtocolwhichisasfollows.
*Whentheserversends"SUBMITNAME"theclientreplieswith
the
*desiredscreenname.Theserverwillkeepsending
"SUBMITNAME"
*requestsaslongastheclientsubmitsscreennamesthat
are
*alreadyinuse.Whentheserversendsalinebeginning
*with"NAMEACCEPTED"theclientisnowallowedtostart
*sendingtheserverarbitrarystringstobebroadcasttoall
*chattersconnectedtotheserver.Whentheserversendsa
*linebeginningwith"MESSAGE"thenallcharacters
following
*thisstringshouldbedisplayedinitsmessagearea.
*/
publicclassChatClient{
BufferedReaderin;
PrintWriterout;
JFrameframe=newJFrame("Chatter");
JTextFieldtextField=newJTextField(40);
JTextAreamessageArea=newJTextArea(8,40);
/**
*ConstructstheclientbylayingouttheGUIand
registeringa
*listenerwiththetextfieldsothatpressingReturnin
the
*listenersendsthetextfieldcontentstotheserver.
Note
*howeverthatthetextfieldisinitiallyNOTeditable,
and
*onlybecomeseditableAFTERtheclientreceivesthe
NAMEACCEPTED
*messagefromtheserver.
*/
publicChatClient(){
//LayoutGUI
textField.setEditable(false);
messageArea.setEditable(false);
frame.getContentPane().add(textField,"North");
frame.getContentPane().add(new
JScrollPane(messageArea),"Center");
frame.pack();
//AddListeners
textField.addActionListener(newActionListener(){
/**
*Respondstopressingtheenterkeyinthe
textfieldbysending
*thecontentsofthetextfieldtotheserver.
Thenclear
*thetextareainpreparationforthenext
message.
*/
publicvoidactionPerformed(ActionEvente){
out.println(textField.getText());
textField.setText("");
}
});
}
/**
*Promptforandreturntheaddressoftheserver.
*/
privateStringgetServerAddress(){
returnJOptionPane.showInputDialog(
frame,
"EnterIPAddressoftheServer:",
"WelcometotheChatter",
JOptionPane.QUESTION_MESSAGE);
}
/**
*Promptforandreturnthedesiredscreenname.
*/
privateStringgetName(){
returnJOptionPane.showInputDialog(
frame,
"Chooseascreenname:",
"Screennameselection",
JOptionPane.PLAIN_MESSAGE);
}
/**
*Connectstotheserverthenenterstheprocessingloop.
*/
privatevoidrun()throwsIOException{
//Makeconnectionandinitializestreams
StringserverAddress=getServerAddress();
Socketsocket=newSocket(serverAddress,9001);
in=newBufferedReader(newInputStreamReader(
socket.getInputStream()));
out=newPrintWriter(socket.getOutputStream(),true);
//Processallmessagesfromserver,accordingtothe
protocol.
while(true){
Stringline=in.readLine();
if(line.startsWith("SUBMITNAME")){
out.println(getName());
}elseif(line.startsWith("NAMEACCEPTED")){
textField.setEditable(true);
}elseif(line.startsWith("MESSAGE")){
messageArea.append(line.substring(8)+"\n");
}
}
}
/**
*Runstheclientasanapplicationwithacloseable
frame.
*/
publicstaticvoidmain(String[]args)throwsException{
ChatClientclient=newChatClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}