
-----------------------------------
Asok
Fri May 20, 2005 9:19 pm

Need help with chat client
-----------------------------------
Hey everyone. I'm trying to modify the code in the networking tutorial (found here http://www.compsci.ca/v2/viewtopic.php?t=8087 ) so that it operates more like a chat client. The main change is basically that the text string input is being passed in from a TextField and the output is being passed out on a TextArea (java.awt.applet).

The problem I'm encountering is that the server will only accept incoming information once and then drop the client. How should I go about making the server *always* accept information from the client?

Any help is greatly appreciated,

Thanks :)
-Asok

-----------------------------------
rizzix
Fri May 20, 2005 11:18 pm


-----------------------------------
for the client it should be something along the lines:import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;

public class JTestClient {
    public static void main(String

PS: this is very very bad design.. but it does explain some concepts such as separating the Model (MessageListModel) and Controller (KeyAdapter) from the View (JTextArea)

PPS: this code only covers sending messages (not recieving them)

-----------------------------------
Asok
Sat May 21, 2005 3:05 pm


-----------------------------------
wow rizzix, thank you so much however the code doesn't seem to run, error is on this line:

Vector messages = new Vector();

and it is "generics not supported in -source 1.2(try source 1.5 to enable generics)" the editor I'm using is JBuilder 2005 Personal.

anyways I thought that it might help if I post my client code here so you can get a sense of what I'm *trying* to do (it interfaces with your server code left unchanged from the tutorial, this build in particular cannot properly send or recieve messages from the server yet but it can connect)

import java.applet.Applet;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;

public class ClientApplet extends WindowAdapter implements ActionListener, ItemListener
{
  Frame frmMenu = new Frame("Chat Client");
  TextArea txaOutput = new TextArea(25,70);
  TextField txtInput = new TextField(62);
  Button btnSend = new Button("Send");
  Panel pnlInterface = new Panel();

  String strInput;
  String strServer = new String("localhost");
  int intPort = 5060;
  boolean blnConnect = false;

  //Menu components
  MenuBar mnuMain = new MenuBar();
  Menu mnuFile = new Menu("File");
  Menu mnuOptions = new Menu("Options");
  Menu mnuOptionsFontColor = new Menu("Font Color");

  //Menu items
  MenuItem mnuFileConnect = new MenuItem("Connect");
  MenuItem mnuFileExit = new MenuItem("Exit");
  CheckboxMenuItem mnuOptionsFontColorBlack = new CheckboxMenuItem("Black",true);

  //class ClientApplet {
    public static void main(String

Anyways I'd just like to thank you again for your help, I was never expecting so much :)

-----------------------------------
Hikaru79
Sat May 21, 2005 3:53 pm


-----------------------------------
wow rizzix, thank you so much however the code doesn't seem to run, error is on this line:

Vector messages = new Vector();

and it is "generics not supported in -source 1.2(try source 1.5 to enable generics)" the editor I'm using is JBuilder 2005 Personal.

The problem is that you're using an outdated version of java (1.2) when we are several years ahead of that (1.5). You can get the newest SDK from http://java.sun.com

-----------------------------------
rizzix
Sat May 21, 2005 11:27 pm


-----------------------------------
asok the problem with your code is that your are establishing a connection to the server every time an action is performed.. you might want to move that snippet up.. i.e keep the connection open.. and simply send a message to the server when an action is performed.. 

also,, close your connection when the windows is closed ;) (look at my snippet on how to do that)

anyways.. i've updated my code to actually send a message. to test it out (after you compile it).. just make sure you first run TestServer (from tutorial) and then run this program.. simple as that.

-----------------------------------
Asok
Sun May 22, 2005 12:52 am


-----------------------------------
hey rizzix :)

I figured out why I was only able to ever send one message. It had to do with the: while ((input = clientIn.readLine()) != null) on the server side.

I got rid of that and can now send as many messages as I want to the server :)

I basically now have only 3 more issues to tackle:
1) getting the server to send it back to display it in the text area. I assume it's the same way as I sent data to the server from the client. But it's 1:40 AM and I'll test that in the morning ;)
2) modifying the server code to allow multiple clients on at the same time. This will probably be the trickiest part because it'll require an overhaul of the server code(flexible array of clients perhaps?) and I'll wait till after I get one client working flawlessly before I attempt to modify the server code more.
3) correcting a bloody EOF error when trying to read a file. (your tutorial helped me out a lot with the concepts of I/O :D) basically I'm using a single object (user) to store everything I need. so the file simply contains a writeObject. the problem is I keep getting the EOF error when trying to read from that file.  The code for that class is posted below, I'm pretty sure it's correct but something is getting messed up to cause the reading to go nuts.


import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class MsgPreferences extends Dialog implements ActionListener 
{
  //Create components
  Button btnSave = new Button("Save Preferences");
  Button btnCancel = new Button("Cancel");
  TextField txtName = new TextField(25);
  TextField txtPort = new TextField(10);
  TextField txtServer = new TextField(25);
  Label lblError = new Label("                                    ");
  
  private String strServer;
  private String strName;
  private String strPort;
  
  //Declare Stream objects
  FileOutputStream outputData; //Stream to create file
  FileInputStream inputData; //Stream to read from a file
  ObjectOutput objSaveData; //Stream to save an object
  ObjectInputStream objGetData; //Stream to retrieve an object

  
  //Constructor
  public MsgPreferences (Frame frmParent)
  {
    //Call the parent's constructor
    super(frmParent, "Preferences" ,true);
    
    //Set up the Dialog box
    Panel pnlLayout = new Panel();
    pnlLayout.setLayout(new FlowLayout());
    pnlLayout.add(new Label("Username: "));
    pnlLayout.add(txtName);
    pnlLayout.add(new Label("Server:         "));
    pnlLayout.add(txtServer);
    pnlLayout.add(new Label("                                                 Port:"));
    pnlLayout.add(txtPort);
    pnlLayout.add(btnSave);
    pnlLayout.add(btnCancel);
    pnlLayout.add(lblError);
    add(pnlLayout);
    
    btnSave.addActionListener(this);
    btnCancel.addActionListener(this);
    
    //Listen for close box
    addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent evt)
      {
        closeStream();
        dispose(); //Destroy the dialog
      }
    });
    openStream();
    readFile();
    setSize(300,200);
    setLocation(200,200);
    show();
  }
  public void openStream()
  {
    try 
    {
      //Create file and object output streams
      outputData = new FileOutputStream("user.txt");
      objSaveData = new ObjectOutputStream(outputData);

      //Create file and object input streams
      inputData = new FileInputStream("user.txt");
      objGetData = new ObjectInputStream(inputData);
      
      lblError.setText("          File Opened             ");
    }
    catch (Exception error) 
    {
      lblError.setText("Error Opening File");
    }
  }
  public void readFile()
  {
    try
    {
      User userCurrent;
      userCurrent = (User) objGetData.readObject();
      txtName.setText(userCurrent.getName());
      txtServer.setText(userCurrent.getServer());
      txtPort.setText(userCurrent.getPort());
    }
    catch (EOFException eof)
    {
      lblError.setText("End of File");
    }
    catch (Exception error) 
    {
      lblError.setText("Error Reading File");
    }
  }
  public void closeStream()
  {
    try
    {
      objSaveData.close(); //Close the object output stream
      outputData.close(); //Close the file output stream
      objGetData.close(); //Close the object input stream
      inputData.close(); //Close the file input stream
    }
    catch (IOException error)
    {
      lblError.setText("Error closing file");
    }
  }
  public void actionPerformed(ActionEvent evt)
  {
      //Determine the object calling this method
      Object objSource = evt.getSource();
  
      if (objSource == btnSave) {
        try {
          //int intPort = Integer.valueOf(txtPort.getText()).intValue();
           User newUser = new User(txtName.getText(), txtServer.getText(),
                                   txtPort.getText());
          objSaveData.writeObject(newUser);
          strServer = txtServer.getText();
          strName = txtName.getText();
          strPort = txtPort.getText();
          //objSaveData.writeUTF(txtName.getText());
          //objSaveData.writeUTF(txtServer.getText());
          //objSaveData.writeUTF(txtPort.getText());
          objSaveData.flush();
          lblError.setText("User Saved");
          
        }
        catch (Exception error) {
          lblError.setText("Error writing to file");
        }
        
      }
      if (objSource == btnCancel) 
      {
      closeStream();
      dispose(); //Destroy the dialog when Cancel button is pressed
      }
    }
    public String setUserName()
    {
      return strName;
    }
    public String setServer()
    {
      return strServer;
    }
    public String setPort()
    {
      return strPort;
    }
 
}


rizzix, I can't thank you enough, your tutorials have been basically the key to understanding all of this (my textbook is terrible haha :))

-----------------------------------
rizzix
Sun May 22, 2005 1:32 am


-----------------------------------
does the User class implement the Serializable interface? it should.. this interface does not define any methods as such.. it simply acts as a flag explictly stating that objects of that class can be serialized (read or written to  a stream).

-----------------------------------
Asok
Sun May 22, 2005 10:32 am


-----------------------------------
yea it does rizzix, here's my user class :)

import java.io.*;

public class User implements Serializable
{
  private String strName;
  private String strServer;
  private String strPort;
  
  //class constructor
  User(String strNameIn, String strServerIn, String strPortIn)
  {
    strName = strNameIn;
    strServer = strServerIn;
    strPort = strPortIn;
  }
  public String getName()
  {
    //Retrieve user name
    return strName;
  }
  public String getServer() 
  {
    //Retrieve server IP/Hostname
    return strServer;
  }
  public String getPort()
  {
    //Retrieve server port
    return strPort;
  }


I'm still trying to figure out why there is the EOF error, it says there is no problem writing only reading but that may not be the actual case.

-----------------------------------
rizzix
Sun May 22, 2005 1:41 pm


-----------------------------------
heh you sure there's something in that file? :P  cuz  ur code: first trys to read from the file.. then when an action is performed.. it writes to the file..

so yea.. you might want to write a dummy object to that file first and then run ur code..

-----------------------------------
Asok
Sun May 22, 2005 2:33 pm


-----------------------------------
when I open the text file all I get is two box characters

so I know SOMETHING is in there but I'm not exactly sure what.

-----------------------------------
rizzix
Sun May 22, 2005 5:24 pm


-----------------------------------
hmm.. well.. empty the file.. and write a dummy object to it.. then run ur program.. post if you still have errors.

-----------------------------------
Asok
Sun May 22, 2005 10:20 pm


-----------------------------------
thanks for the advice rizzix! now that txt file isn't empty because I'm writng the dummy object.  the text file looks like this: 

Â¬Ã­ sr User}Ã—j-d Ã‡Q L  strNamet Ljava/lang/String;L  strPortq ~ L 	strServerq ~ xpt Guestt 5060t 	localhost


the problem now is on the reading side. when I close and reopen it only displays the information in the dummy object. I think it has something to do with the logical aspect of my code. I've posted the updated code here:


import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class MsgPreferences extends Dialog implements ActionListener 
{
  //Create components
  Button btnSave = new Button("Save Preferences");
  Button btnCancel = new Button("Cancel");
  TextField txtName = new TextField(25);
  TextField txtPort = new TextField(10);
  TextField txtServer = new TextField(25);
  Label lblError = new Label("                                    ");
  
  private String strServer = "localhost";
  private String strName = "Guest";
  private String strPort = "5060";
  
  //Declare Stream objects
  FileOutputStream outputData; //Stream to create file
  FileInputStream inputData; //Stream to read from a file
  ObjectOutput objSaveData; //Stream to save an object
  ObjectInputStream objGetData; //Stream to retrieve an object

  
  //Constructor
  public MsgPreferences (Frame frmParent)
  {
    //Call the parent's constructor
    super(frmParent, "Preferences" ,true);
    
    //Set up the Dialog box
    Panel pnlLayout = new Panel();
    pnlLayout.setLayout(new FlowLayout());
    pnlLayout.add(new Label("Username: "));
    pnlLayout.add(txtName);
    txtName.setText(strName);
    pnlLayout.add(new Label("Server:         "));
    pnlLayout.add(txtServer);
    txtServer.setText(strServer);
    pnlLayout.add(new Label("                                                 Port:"));
    pnlLayout.add(txtPort);
    txtPort.setText(strPort);
    pnlLayout.add(btnSave);
    pnlLayout.add(btnCancel);
    pnlLayout.add(lblError);
    add(pnlLayout);
    
    btnSave.addActionListener(this);
    btnCancel.addActionListener(this);
    
    //Listen for close box
    addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent evt)
      {
        closeStream();
        dispose(); //Destroy the dialog
      }
    });
    openStream();
    
    //write dummy object
    try {
      //int intPort = Integer.valueOf(txtPort.getText()).intValue();
       User newUser = new User(txtName.getText(), txtServer.getText(),
                               txtPort.getText());
      objSaveData.writeObject(newUser);
      strServer = txtServer.getText();
      strName = txtName.getText();
      strPort = txtPort.getText();
      //objSaveData.writeUTF(txtName.getText());
      //objSaveData.writeUTF(txtServer.getText());
      //objSaveData.writeUTF(txtPort.getText());
      objSaveData.flush();
      lblError.setText("User Saved");

    }
    catch (Exception error) {
      lblError.setText("Error writing to file");
    }
    
    readFile();
    setSize(300,200);
    setLocation(200,200);
    show();
  }
  public void openStream()
  {
    try 
    {
      //Create file and object output streams
      outputData = new FileOutputStream("user.txt");
      objSaveData = new ObjectOutputStream(outputData);

      //Create file and object input streams
      inputData = new FileInputStream("user.txt");
      objGetData = new ObjectInputStream(inputData);
      
      lblError.setText("          File Opened             ");
    }
    catch (Exception error) 
    {
      lblError.setText("Error Opening File");
    }
  }
  public void readFile()
  {
    try
    {
      User userCurrent;
      userCurrent = (User) objGetData.readObject();
      txtName.setText(userCurrent.getName());
      txtServer.setText(userCurrent.getServer());
      txtPort.setText(userCurrent.getPort());
    }
    catch (EOFException eof)
    {
      lblError.setText("End of File");
    }
    catch (Exception error) 
    {
      lblError.setText("Error Reading File");
    }
  }
  public void closeStream()
  {
    try
    {
      objSaveData.close(); //Close the object output stream
      outputData.close(); //Close the file output stream
      objGetData.close(); //Close the object input stream
      inputData.close(); //Close the file input stream
    }
    catch (IOException error)
    {
      lblError.setText("Error closing file");
    }
  }
  public void actionPerformed(ActionEvent evt)
  {
      //Determine the object calling this method
      Object objSource = evt.getSource();
  
      if (objSource == btnSave) {
        try {
          //int intPort = Integer.valueOf(txtPort.getText()).intValue();
           User newUser = new User(txtName.getText(), txtServer.getText(),
                                   txtPort.getText());
          objSaveData.writeObject(newUser);
          strServer = txtServer.getText();
          strName = txtName.getText();
          strPort = txtPort.getText();
          //objSaveData.writeUTF(txtName.getText());
          //objSaveData.writeUTF(txtServer.getText());
          //objSaveData.writeUTF(txtPort.getText());
          objSaveData.flush();
          lblError.setText("User Saved");
          
        }
        catch (Exception error) {
          lblError.setText("Error writing to file");
        }
        
      }
      if (objSource == btnCancel) 
      {
      closeStream();
      dispose(); //Destroy the dialog when Cancel button is pressed
      }
    }
    public String setUserName()
    {
      return strName;
    }
    public String setServer()
    {
      return strServer;
    }
    public String setPort()
    {
      return strPort;
    }
 
}


Thanks again for all of your help rizzix :)

-----------------------------------
rizzix
Sat May 28, 2005 7:25 pm


-----------------------------------
ok its really simple.. and yes its a logic problem..

first delete the user.txt file.

now edit your code to check to see if user.txt exists.. if it does not exist.. write a dummy object to the file..

that will fix your problems.. btw in order to check if the file exist. you'd have to first create a File object.
