user101285
user101285

Reputation: 111

Working on a java based chatting application using threading

I was trying to send message through threading. dataAvailable is a variable which tells whether message is available on textfield or not. if available dataAvailable is set to true and in run() method if it is true following code is executed. But the problem is in run() it never sees dataAvailable is true and nothing is sent. Help needed.

This is client

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class PeerOne extends JFrame implements Runnable
{
    private static final long serialVersionUID = 1L;

    JTextField outgoing;
    JTextArea incoming;
    JButton send;
    Thread t,t1;
    ObjectOutputStream output;  //for writing objects to a stream
    ObjectInputStream input;    //for reading objects from a stream
    Socket s;
    volatile boolean dataAvailable=false;
    String message = null;
    public PeerOne()
    {
        outgoing = new JTextField();
        outgoing.setEnabled(true);
        outgoing.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(!(e.getActionCommand().isEmpty()))
                {
                    dataAvailable = true;
                    System.out.print("hi");
                }
            }
        });

        this.add(outgoing,BorderLayout.SOUTH);

        incoming = new JTextArea();
        incoming.setEditable(true);
        this.add(new JScrollPane(incoming),BorderLayout.CENTER);
        this.add(incoming);

        setSize(300,150);
        setVisible(true);

        try
        {
            s = new Socket("localhost",5500);
            incoming.append("Connection Successfull..."+"\n");

            output = new ObjectOutputStream(s.getOutputStream());
            output.flush();
            input = new ObjectInputStream(s.getInputStream());

        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }

        t = new Thread(this,"PeerOne");
        System.out.print("New Thread");
        //t1 = new Thread(this,"Two");
        t.start();
    }

    public static void main(String[] args) 
    {
        new PeerOne();
    }

    public void run()
    {   
        while(true)
        {
            if(dataAvailable==true)
            {
                try 
                {
                    System.out.print(0);
                    output.writeObject(outgoing.getText());
                    output.flush();
                    dataAvailable = false;
                }
                catch (IOException e1) 
                {
                    e1.printStackTrace();
                }
            }
            try 
            {
                try 
                {
                    message = (String)input.readObject();

                    incoming.append(message);
                }
                catch (ClassNotFoundException e) 
                {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }       
        }

    }
}

This is server

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class PeerTwo extends JFrame implements Runnable
{
    private static final long serialVersionUID = 1L;
    JTextField outgoing;
    JTextArea incoming;
    JButton send;
    Thread t;
    Socket s;   
    ObjectOutputStream output;  //for writing objects to a stream
    ObjectInputStream input;    //for reading objects from a stream
    volatile boolean dataAvailable=false;
    String message = null;

    public PeerTwo()
    {
        outgoing = new JTextField();
        outgoing.setEnabled(true);
        outgoing.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(!(e.getActionCommand().isEmpty()))
                {
                    dataAvailable = true;
                }
            }
        });

        this.add(outgoing,BorderLayout.SOUTH);

        incoming = new JTextArea();
        incoming.setEditable(true);
        this.add(new JScrollPane(incoming),BorderLayout.CENTER);
        this.add(incoming);

        setSize(300,150);
        setVisible(true);
        try
        {
            ServerSocket ss = new ServerSocket(5500,100);
            s = ss.accept();

            output = new ObjectOutputStream(s.getOutputStream());
            output.flush();
            input = new ObjectInputStream(s.getInputStream());
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }

        t = new Thread(this,"PeerTwo");
        System.out.print("New Thread");
        t.start();



    }

    public static void main(String[] args)
    {
        new PeerTwo();
    }

    public void run() 
    {
            while(true)
            {
                if(dataAvailable==true)
                {
                    try 
                    {
                        System.out.print("bbb");
                        output.writeObject(outgoing.getText());
                        output.flush();
                        dataAvailable = false;
                    }
                    catch (IOException e1) 
                    {
                        e1.printStackTrace();
                    }
                }
                try {
                        try 
                        {
                            message = (String)input.readObject();
                            System.out.print(0);
                            incoming.append(message);
                        }
                        catch (ClassNotFoundException e) 
                        {
                            e.printStackTrace();
                        }
                } catch (IOException e) {
                    e.printStackTrace();
                }       
            }
        }
}

Upvotes: 2

Views: 979

Answers (1)

Vladislav Kysliy
Vladislav Kysliy

Reputation: 3736

This code has several bugs/issues:

  1. Endless loop. Your code wastes processor time. I would recommend use guarded block for write procedure or at least sleep.
  2. Read is blocked. Code doesn't have any checking from input stream.
  3. Working with swing components outside EDT
  4. Application still works when you close application window. (use this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);)

So i would like to suggest hotfix. It will make your code work. PeerOne(client):

public void run() {
        while (true) {
            if (dataAvailable == true) {
                try {
                    System.out.print(0);
                    output.writeUTF(outgoing.getText());
                    output.flush();
                    dataAvailable = false;
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            try {
                if (input.available() > 0) {
                    message = input.readUTF();
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            incoming.append(message);
                            incoming.append("\n");
                        }
                    });
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                TimeUnit.MILLISECONDS.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

PeerTwo(server):

public void run() {
    while (true) {
        if (dataAvailable == true) {
            try {
                System.out.print("bbb");
                output.writeUTF(outgoing.getText());
                output.flush();
                dataAvailable = false;
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        try {
            if (input.available() > 0) {
                message = input.readUTF();
                System.out.print(0);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        incoming.append(message);
                        incoming.append("\n");
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

So as you can i fixed 1-3 problems and used readUTF/writeUTF instead readObject/writeObject to simplify code. The next step is split reading/writing to 2 single threads. You can do it on your own.

Upvotes: 3

Related Questions