?
Solved

Socket Events in Java

Posted on 2005-03-08
14
Medium Priority
?
1,635 Views
Last Modified: 2012-05-05
Hi,

Here is what I'm trying to acheive in terms of retrieving data from sockets connections to my server.

The server can accept multiple socket connections. And as soon as it gets a socket connection it hands it off to a ProcessSocket  class which extends Thread.

while (LISTENING)
        {
        new ProcessSocket(serverSocket.accept()).start();
        }

in the ProcessSocket class I basically do the following

DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte mesg [] = new byte[];
while(true)
   {
     if(din.read()>0)
     {
         din.readFully(mesg);
     }
     else
     {
          Thread.sleep(500);
      }
    }

I feel this is a bad way to monitor a socket for any incoming data. Is there an way I can look for events on a socket when there is data with a third party API maybe? Can someone suggest a better way to do this in Java?

And also what is the limit on how many incoming socket connections a JVM allows to an application?

Any help is appreciated.

Venkatesh.
0
Comment
Question by:Venki533
[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
  • 7
  • 6
14 Comments
 
LVL 92

Expert Comment

by:objects
ID: 13492394
>      if(din.read()>0)

that should be calling available() not read()

     if(din.available()>0)

but that could still block (I assume you are trying to avoid blocking) if there isn't enough data to fill buf
0
 

Author Comment

by:Venki533
ID: 13493017
I did'nt see a  method available() in the DataInputStream class in Java 1.4 api. Blocking would be ideal here. I could'nt find a Class that has methods that would block on a stream read operation until there are bytes. Any ideas if there any classes like that? I could find them in 1.4 api either.

0
 
LVL 92

Expert Comment

by:objects
ID: 13493039
most of the I/O methods will block until data is available, you could use something like this:

DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte mesg [] = new byte[256];
int n = 0;
while ((n=din.read(mesg))>=0)
{
   // process the n bytes read into mesg buffer
}

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.

 
LVL 6

Expert Comment

by:durgaprasad_j
ID: 13493475
hi venki,

>>And also what is the limit on how many incoming socket connections a JVM allows to an application?

I dont think there is any limitation, it depends only on the max socket connections set in the ServerSocket.

>>  Can someone suggest a better way to do this in Java?
In  C++, specially for this purpose, there are functions like poll and select [ which will notify you after input comes].
I dont know exact functionality in java. But you could use JNI to use that functionality in C++.

Hope this helps
0
 

Author Comment

by:Venki533
ID: 13500644
Hi Objects,
   The method read() seems to return a -1 when there is no data on the input stream and runs in a continuous loop :/

Also is there a way to detect socket disconnect on the client side without depending on exceptions?

The following is my code. Can you confirm if I'm doing something wrong?

------------------------------------------------------------------------------------
public class SocketHandler implements Runnable {
      private Socket sock=null;
      private DataInputStream din = null;
      private String message=null;
      public SocketHandler(Socket socket){
            this.sock=socket;
      }
      public void run() {
            try {
                        din =new DataInputStream( new BufferedInputStream(sock.getInputStream()));
                  processSocketStream(bin);
            } catch (IOException e) {
                  e.printStackTrace();
                  cleanup();
            }
      }
      
      private void processSocketStream(DataInputStream dins) throws IOException{
            ReadData rdata = new ReadData(dins);
            while(true){
                  System.out.println("SocketHandler::processSocket:: message = "+rdata.message());
            }
      }
      
      private void cleanup(){
         try {
            if(sock!=null)      {
                  sock.close();
            }
                if(din!=null){
                    din.close();
                }
          } catch (IOException e) {
                  e.printStackTrace();
         }
      }

-----------------------------------
public class ReadData {
      private DataInputStream din = null;
      public ReadData(DataInputStream dins){
            this.din = dins;
      }
      public String message() throws IOException
      {
            byte [] message = new byte[20];
            int n=0;
            n=din.read(message);
            System.out.println("ReadData::message():: bytesRead = "+n);
            return new String(message);
      }
}

--------------------------------------------
Durga Prasad thank you for the help. But I do not want to add the complexity of JNI into my code right now, as that involves a learning curve. And I heard the max number of socket connections is dependent on the OS?

I increased the points to 600 for the extra questions i'm posing.

Thank You,

Venkatesh.
0
 

Author Comment

by:Venki533
ID: 13500667
I guess the max points that can be awarded is 500. lol. Sorry about that.

0
 

Author Comment

by:Venki533
ID: 13500677
messed up again
0
 
LVL 92

Expert Comment

by:objects
ID: 13501429
> The method read() seems to return a -1

it returns -1 on eof

> Also is there a way to detect socket disconnect on the client side without depending on exceptions?

I don't think so

> public String message() throws IOException

What is your intention for this message?  What is actually being sent to it?

0
 

Author Comment

by:Venki533
ID: 13502258
it returns -1 on eof
when bytes are written to the stream by the client, how can i just make the read() method read all of it and just wait for the next set of bytes then?

What is your intention for this message?  What is actually being sent to it?
Message could be anything. Once i get a string back from the socket input stream, i'm gonna hand it off to a message handler and process it based on its header field values.

So  what I want  to achieve is to have a method read data on the input stream every time something new shows up until the client closes the socket connection.

 
0
 
LVL 92

Expert Comment

by:objects
ID: 13502273
If you are passing strings as messages then a BufferedReader may be more applicable for reading the messages.
How are the message being written on the sending end.
0
 

Author Comment

by:Venki533
ID: 13502687
thanx for all your help. I'm sick of not having events to know that there is data to read on the socket's stream. I can not believe no one has run into this problem before using Java. All I wanted to do was have a reader sit there until a new message appears on the stream,  just like serverSocket.accept() sits there until a new socket connection requests arrives.


while (true){
    read(byte); // block damnit, I dont need the lame -1
}

without the while  loop going into a continuous loop taking up cpu, and without having to use a Thread.sleep();

Venkatesh.


0
 
LVL 92

Accepted Solution

by:
objects earned 2000 total points
ID: 13502721
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while (null!=(in.readLine()))
{
   // process line
}
0
 

Author Comment

by:Venki533
ID: 13502960


I dont think that while loop will work. It will miss the first line of the message. Am I wrong thinking that?    
0
 
LVL 92

Expert Comment

by:objects
ID: 13502966
that loop will read each line (terminated by a newline), it won't lose the first line
0

Featured Post

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

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

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Suggested Courses
Course of the Month10 days, 19 hours left to enroll

770 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