?
Solved

A Simple Multicast Chat Program

Posted on 2003-03-25
25
Medium Priority
?
534 Views
Last Modified: 2012-08-14
Hi All,

I am trying to complete an excersize in Java, to create a Simple Multicast Chat Program. I have been given the following code:

public class Chat {

public static void main (String argv[]) {
  MulticastSender msend = new MulticastSender ("224.123.111.101", 45000, 1);
  Thread sender = new Thread (msend);
  ChatWindow cw = new ChatWindow (msend, argv[0]);
  sender.start ();

  MulticastSniffermsniff=new MulticastSniffer("224.123.111.101",45000,1,cw.getOutput());
  Thread sniffer = new Thread (msniff);
  sniffer.start ();
  }
}
 

import java.awt.*;
import java.awt.event.*;

public class ChatWindow extends Frame implements ActionListener {
TextArea output = new TextArea ();
TextField input = new TextField ("", 20);
Button add = new Button ("Say");
Label say = new Label ("Say :");
MulticastSender msend = null;
String name = "";

public ChatWindow (MulticastSender msend, String name) {
  this.name = name;
  this.msend = msend;
  buildGui ();
  }

public void actionPerformed (ActionEvent e) {
  String send = "(" + name + ") " + this.input.getText ();
  msend.send (send.getBytes ());
  input.setText ("");
  }

public TextArea getOutput () {
  return (output);
  }

public void buildGui () {
  output.setEditable (false);
  this.setSize (400, 400);
  this.setLayout (new GridBagLayout ());
  Panel inputLayout = new Panel ();
  inputLayout.setLayout (new GridBagLayout ());
  GridBagConstraints gbcInput = new GridBagConstraints ();
  gbcInput.anchor = GridBagConstraints.WEST;
  gbcInput.fill = GridBagConstraints.NONE;
  gbcInput.weighty = 0;
  gbcInput.gridx = 0;
  gbcInput.gridy = 0;

  gbcInput.weightx = 0;
  inputLayout.add (say, gbcInput);
  gbcInput.fill = GridBagConstraints.HORIZONTAL;
  gbcInput.gridx = 1;
  gbcInput.weightx = 1;
  inputLayout.add (input, gbcInput);
  gbcInput.gridx = 2;
  gbcInput.fill = GridBagConstraints.NONE;
  gbcInput.weightx = 0;
  inputLayout.add (add, gbcInput);
  add.addActionListener (this);

  GridBagConstraints gbcOutput = new GridBagConstraints ();
  gbcOutput.anchor = GridBagConstraints.CENTER;
  gbcOutput.fill = GridBagConstraints.BOTH;
  gbcOutput.weightx = 1;
  gbcOutput.weighty = 1;
  gbcOutput.gridx = 0;
  gbcOutput.gridy = 0;
  this.add (output, gbcOutput);
  gbcOutput.anchor = GridBagConstraints.WEST;
  gbcOutput.gridy = 1;
  gbcOutput.weighty = 0;
  this.add (inputLayout, gbcOutput);
  this.show ();
  }
}

I have been asked to:
Develop an appropriate sender class
Develop an appropriate sniffer class

Im not really sure where to start, can anyone help?
0
Comment
Question by:mtcmedia
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 11
  • +1
25 Comments
 
LVL 15

Expert Comment

by:ozymandias
ID: 8205666
There are lots of projects developing multicasting applications in Java . Here is one example where you can get the complete set of libraries and the source code, so you can have a look at how best to implement it :

http://www.experimentalstuff.com/Technologies/JRMS/
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8206119
Thanks for that, and I have read a lot of resources similar to above - but I am still unsure how to build the two remaining classes from the above source. Can anyone help?
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8206422
This resource is a Java MultiCast Chat program.
It implements a MulticastSender and MulticastReceiver (similar in function to your MulticastSniffer).

Have a look at the source.

http://jmc.logicnet.ro/
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:mtcmedia
ID: 8206497
I cant open .jar files.

Can someone please post the classes I need? If so that would be GREAT!

Thanks in advance for your help!
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8206861
winzip will open jar files.

However, in VERY BASIC form here are the classes.

public class Chat {

     public static void main (String argv[]) {
          MulticastSender msend = new MulticastSender ("230.0.0.1", 4446, 1);
          Thread sender = new Thread (msend);
          ChatWindow cw = new ChatWindow (msend, "test");
          sender.start ();

          MulticastSniffer msniff = new MulticastSniffer("230.0.0.1",4446,1,cw.getOutput());
          Thread sniffer = new Thread (msniff);
          sniffer.start ();
     }
}
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8206863
import java.awt.TextArea;
import java.net.*;
import java.io.*;

public class MulticastSniffer extends Thread{

     public static int MSG_SIZE = 1024;

    protected MulticastSocket socket;
    protected InetAddress mcAddress;
    protected InetAddress lAddress;
    protected boolean interrupt = false;
    protected int port;

     TextArea output;

     public MulticastSniffer(String address, int port, int dunno, TextArea ta){
          output = ta;
          this.port = port;
        try {
            mcAddress = InetAddress.getByName(address);
            lAddress = InetAddress.getLocalHost();
            System.out.println(lAddress);
        } catch(UnknownHostException e) {
            e.printStackTrace();
        }
     }

     public void run(){
        DatagramPacket packet;
        try {
            socket = new MulticastSocket(port);
            socket.setInterface(lAddress);
            socket.joinGroup(mcAddress);
             while (!interrupt){
                    byte[] buf = new byte[MSG_SIZE];
                    packet = new DatagramPacket(buf, buf.length);
                    socket.receive(packet);
                    String received = new String(packet.getData());
                    System.out.println("Data : " + received);
                    output.append(received + "\n");
               }
               socket.leaveGroup(mcAddress);
               socket.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
     }

}
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8206865
import java.net.*;
import java.io.*;

public class MulticastSender extends Thread{

     protected DatagramSocket socket = null;
     protected String mcAddress;
     protected int port;
     protected int dunno;
     public boolean interrupt = false;

     public MulticastSender(String address, int port, int i){
          mcAddress = address;
          this.port = port;
          dunno = i;
     }

     public void run(){
          /*
          try{
               socket = new DatagramSocket(port);
          }catch(SocketException e) {
             e.printStackTrace();
          }
          while (!interrupt){
          }
          socket.close();
          */
     }

     public void send(byte[] b){
          try{
               socket = new DatagramSocket(port-1);
               InetAddress group = InetAddress.getByName(mcAddress);
               DatagramPacket packet = new DatagramPacket(b, b.length, group, port);
               socket.send(packet);
               socket.close();
          }catch (IOException e) {
             e.printStackTrace();
          }
     }

}
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8206872
If you run two copies of Chat whatever you type in one windows will appear in the other.

0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8208887
Hey ozymandias,

Great thanks for that, I am at work just now, but will try and run it as soon as I get home.

It all seems clear enough, apart from one question. In the multicastsender class, when does the send method get called? I notice you have commented out the run, so should the send method body be inside run? Or just call send from run? Im not sure how this bit works.

Thanks again!
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8208926
In the sender I have commeneted out the run portion because I had to test the program on one computer. If I bind one instance of the thread to the send port then I cannot run another instance of the program because the port will always be in use.

So for testing I create the socket on each send() rather than in run().

The send method() gets called by the ChatWindow when you click on the "say" button.
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8208975
Here is a modified version of the sender that will allow two instance of Chat to run on the same machine. The run() method will search for an available send port if the normal one is in use.

import java.net.*;
import java.io.*;

public class MulticastSender extends Thread{

     protected DatagramSocket socket = null;
     protected String mcAddress;
     protected int port;
     protected int dunno;
     public boolean interrupt = false;

     public MulticastSender(String address, int port, int i){
          mcAddress = address;
          this.port = port;
          dunno = i;
     }

     public void run(){
          boolean isBound = false;
          int sendport = port;
          while (!isBound){
               try{
                    socket = new DatagramSocket(sendport);
                    isBound = true;
               }catch(SocketException e) {
                  sendport++;
               }
          }
          while (!interrupt){
          }
          socket.close();
     }

     public void send(byte[] b){
          try{
               InetAddress group = InetAddress.getByName(mcAddress);
               DatagramPacket packet = new DatagramPacket(b, b.length, group, port);
               socket.send(packet);
          }catch (IOException e) {
             e.printStackTrace();
          }
     }

}
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8209350
Thanks for that. But the first class you posted will work if I run it on two different machines? And provided I uncomment the run?
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8209358
Also why dont you have to run joinGroup in sender?
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8209437
Forget that last question about joinGroup - but answer the previous one if possible please :)
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8209540
OK I have it running using two seperate machines and the first Sender class. Can you please answer these final questions:

* socket = new DatagramSocket(port-1) Why do I need to create more than one DatagramSocket on different ports? Whenever the packet is sent, the socket is closed, so why cant I just re open that socket on the same port for the next packet - instead of using a different port everytime.

* how can I create the MulticastSocket and DatagramSocket on the same port number - surely this shouldnt work?

0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8209613
>> But the first class you posted will work if I run it on two different machines? And provided I uncomment the run?

Yes, you would have to uncomment the run, but also change the send method because currently it creates and closes the socket so remove the first and last line of the code inside the try block.


>> socket = new DatagramSocket(port-1) Why do I need to create more than one DatagramSocket on different ports?

You don't. But you can't bind the server and the receiver to the same port.

>>  Whenever the packet is sent, the socket is closed, so why cant I just re open that socket on the same port for the next packet - instead of using a different port everytime.


Yes, whenever the packet is sent, the socket is closed, but it shouldn't be. The run method binds to the socket and then holds it until interrupted. The send method can then use the socket over and over again without having to recreate it each time.

>> how can I create the MulticastSocket and DatagramSocket on the same port number - surely this shouldnt work?

You can't, and as far as I can see you don't.
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8217826
>> how can I create the MulticastSocket and DatagramSocket on the same port number - surely this shouldnt work?

You can't, and as far as I can see you don't.
-------------------------------------------------

The above, it looks to me like i am?

MulticastSender msend = new MulticastSender ("224.123.111.101", 45000, 1);

 MulticastSniffer msniff=new MulticastSniffer("224.123.111.101",45000,1,cw.getOutput());

Sniffer and sender on the same port?
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 8218252
Yes, but if you look at the implementation of sender, it does not just use port 45000. It "tries" to use it but if it can't it tries 45001 and then 45002 and so on until it finds a free port.
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8220172
I used the first class you posted... and it doesnt have the increasing port value... and I dont get any exception when I run it - it seems to work.
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8220232
I can see that the second class you gave me will keep checking for the next port to create the sender on BUT as I said, when I use the first class, it will just use the port number I give it.

Then, if I try to run another chat it wont work - as expected. BUT once the sender is setup, I then setup the sniffer on the same port. How can this work?
0
 
LVL 15

Accepted Solution

by:
ozymandias earned 280 total points
ID: 8220632
I'm not sure.
I would have to assume that it is possible to have a MulticastSocket and a DatagramSocket bound to the same port. Since the MulticastSocket only listens maybe there is no contention so it's allowed.
0
 
LVL 2

Author Comment

by:mtcmedia
ID: 8221072
ok :) I accept that
0
 

Expert Comment

by:CleanupPing
ID: 9058493
mtcmedia:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
LVL 15

Expert Comment

by:jimmack
ID: 9732581
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept ozymandias' comment as answer.

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jimmack
EE Cleanup Volunteer
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month8 days, 16 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question