2

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();
                }       
            }
        }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user101285
  • 111
  • 3
  • 11
  • You have two dataAvailable variables which are in different classes and therefore aren't shared; setting one does not set the other. – pjc50 Dec 17 '13 at 17:34
  • dataAvailable is used restrict to write to output stream but code to read message is free from any conditional statement.When dataAvailable is true in PeerOne, run() should be able to read dataAvailable as true and send the msg but it isn't and if i write condition as dataAvailable==false it sends msg –  Dec 17 '13 at 18:16
  • Didn't you try to ask this same question yesterday, under a different account? – Robert Harvey Dec 17 '13 at 18:44
  • You have two dataAvailable variables. – pjc50 Dec 17 '13 at 20:05

1 Answers1

3

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.

Community
  • 1
  • 1
Vladislav Kysliy
  • 3,488
  • 3
  • 32
  • 44
  • Wasn't going to apply for production but suggestions are welcomed. Nicely pointed out the issues one by one. – user101285 Mar 01 '16 at 15:05