Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Need help with chat client
Index -> Programming, Java -> Java Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Asok




PostPosted: Fri May 20, 2005 9:19 pm   Post subject: 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 Smile
-Asok
Sponsor
Sponsor
Sponsor
sponsor
rizzix




PostPosted: Fri May 20, 2005 11:18 pm   Post subject: (No subject)

for the client it should be something along the lines:
Java:
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[] args) {
        try {
            final JFrame frame = new JFrame("JTestClient");
            final Dimension screenSize = frame.getToolkit().getScreenSize();
            final String addr = args.length == 0 ? "localhost" : args[0];
            final Socket server = new Socket(addr, 5060);
            final PrintWriter serverOut = new PrintWriter(
                new BufferedWriter(
                    new OutputStreamWriter(server.getOutputStream())
                )
            );
           
            // message model of our chat client
            class MessageListModel extends AbstractListModel {
                final Vector<String> messages = new Vector<String>();

                public void addMessage(String msg) {
                    messages.addElement(msg);
                    final int lastIndex = messages.size() - 1;
                    fireIntervalAdded(this, lastIndex, lastIndex);
                }
               
                public int getSize() {
                    return messages.size();
                }
               
                public String getElementAt(int index) {
                    return messages.elementAt(index);
                }
            };
           
            final MessageListModel msgListModel = new MessageListModel();
            frame.add(BorderLayout.CENTER,
                new JScrollPane(new JList(msgListModel)));
           
            final JTextArea jtaMessageInput = new JTextArea();
            jtaMessageInput.addKeyListener(
                new KeyAdapter() {
                    public void keyTyped(KeyEvent e)    {
                        if (e.getKeyChar() == KeyEvent.VK_ENTER) {
                            String msg = jtaMessageInput.getText();
                            msg = msg.substring(0, msg.length()-1);
                            msgListModel.addMessage(msg);
                            serverOut.println(msg);
                            serverOut.flush();
                            jtaMessageInput.setText("");
                        }
                    }
                }
            );
            jtaMessageInput.setBorder(BorderFactory.createEtchedBorder());
            frame.add(BorderLayout.SOUTH, jtaMessageInput);
           
            // close connection upon exit
            frame.addWindowListener(
                new WindowAdapter() {
                    public void windowClosing(WindowEvent we)  {
                        try {
                            server.close();
                        } catch (Exception e) {
                            System.err.println(e);
                        }
                    }
                }
            );
           
            frame.setBounds(screenSize.width/4, screenSize.height/4,
                            screenSize.width/2, screenSize.height/2);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           
            frame.setVisible(true);
            jtaMessageInput.requestFocus();
        } catch (Exception e) {
            System.err.println(e);
        }
    }
}


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




PostPosted: Sat May 21, 2005 3:05 pm   Post subject: (No subject)

wow rizzix, thank you so much however the code doesn't seem to run, error is on this line:

Vector<String> messages = new Vector<String>();

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)

Java:
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[] args)
    {
      ClientApplet myClientApp = new ClientApplet();
      myClientApp.designLayout();
      myClientApp.createInterface();
    }
    public void createInterface()
    {
      //Create the Menu Bar
      //File Menu
      mnuMain.add(mnuFile);
      mnuFile.addActionListener(this);
      mnuFile.add(mnuFileConnect);
      mnuFile.addSeparator();
      mnuFile.add(mnuFileExit);

      //Options Menu
      mnuMain.add(mnuOptions);
      mnuOptions.addActionListener(this);
      mnuOptions.add(mnuOptionsFontColor);
      mnuOptionsFontColor.addActionListener(this);
      mnuOptionsFontColor.add(mnuOptionsFontColorBlack);
      mnuOptionsFontColorBlack.addItemListener(this);

      //Attach the menu bar to the frame
      frmMenu.setMenuBar(mnuMain);

      //Set up the components and the frame
      txaOutput.setForeground(Color.black);
      txtInput.setForeground(Color.black);
      txtInput.requestFocus();
      txaOutput.setEditable(false);
      frmMenu.add(pnlInterface);

      frmMenu.addWindowListener(this);
      frmMenu.setSize(600,500);
      frmMenu.show();
    }
    public void actionPerformed(ActionEvent evt)
    {
      //Determine which menu item was selected
      String strMenuItem = evt.getActionCommand();
      //Determine the object calling this method
      Object objSource = evt.getSource();
      if (strMenuItem.equals("Exit")) {
        System.exit(0);
      }
      else if (strMenuItem.equals("Connect")) {
          //Source Code Credit: Rizzix of CompSci.ca. Tutorial available publically here: http://www.compsci.ca/v2/viewtopic.php?t=8087
           try {
             String input = txtInput.getText();
 
             BufferedReader in = new BufferedReader(
                   new InputStreamReader(System.in));
 
              // establish connection to server
              txaOutput.append("Attempting to connect to: " + strServer + " (" + intPort + ")" + "\n");
              Socket server = new Socket(strServer, intPort);
 
 
             // establish an output stream with server
             PrintWriter serverOut = new PrintWriter(
                 new BufferedWriter(
                     new OutputStreamWriter(server.getOutputStream())
                   )
                  );
 
             // write Strings to server
             //while (!(input = in.readLine()).equals("__END__")) {
             //      serverOut.println(input);
              //     serverOut.flush();
            //   }
            if (objSource == txtInput || objSource == btnSend) {
 
             strInput = txtInput.getText();
             serverOut.println(strInput);
             serverOut.flush();
             txtInput.setText("");
             txtInput.requestFocus();
          }
 
            // server.close(); // close connection
           }
           catch (Exception e) {
             //System.out.println(e);
             txaOutput.append("Error: " + e + "\n");
             blnConnect = false;
 
           }
      }
       
    }

   
    public void itemStateChanged(ItemEvent evt)
    {
      //Determine the state of checkbox menu item
      int intState = evt.getStateChange();
    }
    public void windowClosing(WindowEvent evt)
    {
      //Exit to the operating system
      System.exit(0);
    }
    public void designLayout()
    {
      pnlInterface.setLayout(new FlowLayout());
      pnlInterface.add(txaOutput);
      pnlInterface.add(txtInput);
      pnlInterface.add(btnSend);
      txtInput.addActionListener(this);
      btnSend.addActionListener(this);
    }
}


Anyways I'd just like to thank you again for your help, I was never expecting so much Smile
Hikaru79




PostPosted: Sat May 21, 2005 3:53 pm   Post subject: (No subject)

Asok wrote:
wow rizzix, thank you so much however the code doesn't seem to run, error is on this line:

Vector<String> messages = new Vector<String>();

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




PostPosted: Sat May 21, 2005 11:27 pm   Post subject: (No subject)

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 Wink (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




PostPosted: Sun May 22, 2005 12:52 am   Post subject: (No subject)

hey rizzix Smile

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 Smile

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 Wink
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 Very Happy) 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.

code:

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 Smile)
rizzix




PostPosted: Sun May 22, 2005 1:32 am   Post subject: (No subject)

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




PostPosted: Sun May 22, 2005 10:32 am   Post subject: (No subject)

yea it does rizzix, here's my user class Smile
code:

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.
Sponsor
Sponsor
Sponsor
sponsor
rizzix




PostPosted: Sun May 22, 2005 1:41 pm   Post subject: (No subject)

heh you sure there's something in that file? Razz 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




PostPosted: Sun May 22, 2005 2:33 pm   Post subject: (No subject)

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




PostPosted: Sun May 22, 2005 5:24 pm   Post subject: (No subject)

hmm.. well.. empty the file.. and write a dummy object to it.. then run ur program.. post if you still have errors.
Asok




PostPosted: Sun May 22, 2005 10:20 pm   Post subject: (No subject)

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:
Quote:

¬í 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:

code:

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 Smile
rizzix




PostPosted: Sat May 28, 2005 7:25 pm   Post subject: (No subject)

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.
Display posts from previous:   
   Index -> Programming, Java -> Java Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 13 Posts ]
Jump to:   


Style:  
Search: