?
Solved

non blocking socket network sending and receiving

Posted on 2005-05-02
11
Medium Priority
?
2,062 Views
Last Modified: 2012-06-27
Hi,

I have two sockets within a program. I want to send data from the local host using one socket. The other socket is used to receive data from other hosts. I wish to implement both of these together within one main program (No usage of any threads). I realize I have to use Java NIO, specifically the datagramchannel class (I'm using UDP). How do I generally go about doing this? Data may arrive and need to be sent asynchronously. That's the reason I'm trying to avoid blocking sockets.

Thanks
0
Comment
Question by:blaze_wk
  • 4
  • 4
  • 2
  • +1
11 Comments
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 13909818
Here are some references that may help you:
    http://www.onjava.com/lpt/a/2742 (see #1 Multiplexed IO)
    http://javaalmanac.com/egs/java.nio/NbClientSocket.html
    http://www-106.ibm.com/developerworks/java/library/j-javaio/

Regards,
Jim
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13909882
>> (No usage of any threads)

Why not? Here's a Datagram NIO example:

http://cvs.limewire.org/fisheye/viewrep/~raw,r=1.14/misc/chord/edu/ucr/cs/chord/Connector.java
0
 

Author Comment

by:blaze_wk
ID: 13909909
Thanks Jim. There's not much information on DatagramChannel there. Maybe some code would help explain it a little?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:blaze_wk
ID: 13909981
Thanks CEHJ, That code looks really long and complicated. Is there a shorter version of it somewhere? I'm very new to java nio so if there's some good introductory datagram channel codes that I can look through. That would be good.

Thanks again
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 1200 total points
ID: 13910255
Here's one that sends to a time server. Don't worry about the 'bug'. Unless i'm missing something, the author is describing behaviour that is expected:


SNIP================================================


import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.net.SocketAddress;
import java.net.InetSocketAddress;

/**
 * Test non-blocking DatagramChannel bug. Sends one datagram to the "time"
 * service on port 37 with a non-blocking DatagramChannel. Then loops for a
 * while receiving datagrams. The first to arrive is the expected reply.
 * Thereafter, the same address will be returned forever (or until another real
 * datagram arrives) but no data will be transferred into the buffer. The
 * channel behaves the same way if placed in non-blocking before the initial
 * datagram is sent or after.
 *
 * @author Ron Hitchens (ron@ronsoft.com)
 * @version $Id: DGNonBlockBug.java,v 1.1 2002/04/28 20:52:17 ron Exp $
 */
public class DGNonBlockBug {
      public static void main(String[] argv) throws Exception {
            String target = "time.nist.gov";

            if (argv.length > 0) {
                  target = argv[0];
            }

            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.flip(); // make it empty (RFC 868)

            DatagramChannel channel = DatagramChannel.open();
            ;
            channel.configureBlocking(false);

            channel.send(buffer, new InetSocketAddress(target, 37));

            System.out.println("Sent one Datagram to " + target);

            // would potentially loop forever
            for (int i = 0; i < 10; i++) {
                  buffer.clear();
                  buffer.putInt(0, 0);

                  SocketAddress sa = channel.receive(buffer);

                  if (sa == null) {
                        System.out.println("no datagram ready, " + "sleeping one second");
                        Thread.sleep(1000);
                  } else {
                        int value = buffer.getInt(0);
                        System.out.println(new java.util.Date(value));
                        buffer.flip();
                        System.out.println("Received datagram from " + sa + ": " + buffer
                                    + ", value=" + Integer.toHexString(value));
                  }
            }
      }
}
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13910824
blaze_wk,
As you are using the connectionless Datagram sockets I am not sure what you can gain much by using NIO (unless you are receiving from many ports).
If that is not your case and you are receiving using same port then you can probably use the standard Datagram socket and handle the requests using a Thread Pool (hand off those requests to a buffer which will be processed by the Thread Pool Handlers).
Changing the Datagram receive/send buffers can prove helpful as well.
We use this method to collect SNMP information from 100,000 devices concurrently without any problem.
0
 

Author Comment

by:blaze_wk
ID: 13914440
hi aozarov,

the thing is i'm trying to send information from socket A and receive information simultaneously from socket B. I'm trying to do it without using threads at all. Can this be done using the normal datagramsocket? Wouldn't datagramsocket block the receive and send sockets until it receives data. If it does, then when my program is waiting for data and no data arrives then it will wait forever, and I can't send any data during this period. Am i missing something here or is there a way to use the normal datagramsocket that doesn't block?

Thanks
0
 

Author Comment

by:blaze_wk
ID: 13914479
Hi CEHJ,

Correct if I'm wrong regarding this program. The program send out one datagram through one socket then it enters a loop which checks the sa socket 100 times to see if there is anything to be received. Then the program ends. Is there anything I'm missing?

0
 
LVL 15

Assisted Solution

by:aozarov
aozarov earned 300 total points
ID: 13914947
>>I'm trying to do it without using threads at all.  Can this be done using the normal datagramsocket?
If you want to send and receive simultaneously you will need to have at least two threads.
One will be blocked on read and you can use the other (e.g. the main thread) for the write.
That threads requirement also applies when using Selector (unless you want to use select(long timeout) inside a loop which is not efficient).
Here is an example of using the standard datagramsocket with two threads:
import java.io.*;
import java.net.*;

public class Main
{
      public static void main(String st[]) throws Exception
      {
            final DatagramSocket socket = new DatagramSocket(13);
            new Thread("Receiver")
            {
                  public void run()
                  {
                        try
                        {
                              byte[] inbuf = new byte[256];  // default size
                              DatagramPacket packet = new DatagramPacket(inbuf, inbuf.length);
                              socket.receive(packet);

                              // Data is now in inbuf
                              int numBytesReceived = packet.getLength();
                              // process new message.. e.g.
                              System.out.println("Got -> " + new String(inbuf, 0, numBytesReceived));
                        }
                        catch (SocketException e)
                        {
                        }
                        catch (IOException e)
                        {
                        }

                  }
            }.start();

            // have here your sender logic
            byte[] buffer = "hello world\n".getBytes();
            InetAddress toHost = InetAddress.getLocalHost();
            int toPort = 13;
            DatagramPacket request = new DatagramPacket(buffer, buffer.length, toHost, toPort);
            socket.send(request);      
      }
}
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13916593
>>Correct if I'm wrong regarding this program

The program sends a packet to a time server, which returns a packet containing a time. The return value is checked ten times before exiting (ignore that bit)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13916738
:-)
0

Featured Post

Independent Software Vendors: 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!

Question has a verified solution.

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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses
Course of the Month16 days, 3 hours left to enroll

850 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