[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Unexpected timeout error

Posted on 2005-04-10
18
Medium Priority
?
229 Views
Last Modified: 2010-03-31
Hey all...

I have a client and a server application. What I'm trying to do here, is have one socket write a string to the other; while, of course, the other reads that string....

Okay, both of the two applications use these methods to read and write data, to and from a socket:

            // Write
            protected void write( Socket sock, String str )
            {
                try
                {
                    if ( sock == null )
                        throw new Exception();
                   
                    if ( wr == null )
                        wr = new BufferedWriter( new OutputStreamWriter( sock.getOutputStream() ) );
                    wr.write( str );
                    wr.flush();
                } catch ( Exception e )
                {
                    setStatus( "Socket exception has occured." );
                    e.printStackTrace( System.out );
                }
            }



        // Read
        protected String read( Socket sock )
        {
            try
            {
                if ( sock == null )
                    throw new Exception();
               
                if ( rd == null )
                {
                    rd = new BufferedReader( new InputStreamReader( sock.getInputStream() ) );
                }
                String str;
                String ret = "";
                while ( (str = rd.readLine()) != null )
                {
                    ret += str;
                }
               
                return ret;
            } catch ( Exception e )
            {
                setStatus( "Socket exception has occured." );
                e.printStackTrace( System.out );
            }
           
            return null;
        }


Now, here's what is suppose to happen:

...
CLIENT writes "password:2" to SERVER
SERVER reads "password:2" from CLIENT
SERVER writes "g" to CLIENT
CLIENT reads "g" from SERVER
...

However, it only completes stage one with no problems (CLIENT writes "password:2" to SERVER); the Client writes the String, then starts reading from the socket (well; blocking until it gets some data). However, the server isn't reading anything.. It all comes to a hault, when the Client throws a 20 second timeout exception. So, I'm guessing there's something wrong with my   read(Socket)   method?

Does it look dodgey at all? lol.

Regards;
>> IM
0
Comment
Question by:InteractiveMind
  • 6
  • 5
  • 5
  • +1
18 Comments
 
LVL 7

Expert Comment

by:CajunBill
ID: 13749393
So I'm guessing that Server hangs on the rd.readline, is that correct?
Perhaps it is because Client is not writing an end of line??

HTH
Bill
0
 
LVL 92

Assisted Solution

by:objects
objects earned 400 total points
ID: 13749430
Try using a PrintWriter instead of a BufferedWriter
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 13750553
I would use a PrintWriter too, with flush on new-line set to true:

PrintWriter pw = new PrintWriter ( sock.getOutputStream (), true ) ;
pw.println ( str ) ;
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 25

Author Comment

by:InteractiveMind
ID: 13752064
Thanks all.
I've changed the write() method to this:

        protected void write( Socket sock, String str )
        {
            try
            {
                if ( sock == null )
                    throw new Exception();
               
                if ( wr == null )
                    wr = new PrintWriter( sock.getOutputStream(), true );
                wr.println( str );
            } catch ( Exception e )
            {
                setStatus( "Socket exception has occured." );
                e.printStackTrace( System.out );
            }
        }

but I'm having the same problem (timeout exception).. Which, CajunBill was correct about: is occuring on the Clients' rd.readLine() call.

Perhaps I need to change the read() method also??

Regards;
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 13752218
At the client, are you calling the setSoTimeout () method on the socket anywhere?
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 13752239
By the way, how many times are you calling the write () and read () methods? You should not create a new PrintWriter and BufferedReader everytime you call those methods. Instead, you should create them once (maybe in the constructor) and maintain them as data-members of the class and re-use the same instances everytime.
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13753998
I've temporarily removed the setSoTimeout() calls. I've initialized the PrintWriter and BufferedReader from outside the read() and write() methods, although I have so far, only called each one once.

Still no change... I've set the server to read the String, then output it, like so:

String data = read();
System.out.println( data );

But, it gets stuck on the read(); call.

This is really strange. Agreed? lol.. I'm not the greatest programmer obviously, so it must be something I've done (or, something I've not done).. But I just can't make sense of it..
I'm only connecting to localhost here, and it's connecting fine, but no data is able to get transferred: what is the likelyhood of my firewall allowing the connections, but blocking any data transfer?? (I'm sure; and kind of hoping very low, but...?).

Cheers.
0
 
LVL 7

Expert Comment

by:CajunBill
ID: 13755871
IM, hope you don't mind if I ask for a little clarification here.

First, how do Client and Server share the socket variable (in other words, how sure are you that they are actually talking to each other, instead of talkking to the ether?  )
Also, please let us know if the situation is as follows:

- Client runs first, (not that this should be necessary, but just to clarify since problems are happening right now)
- Client prints to scket, then hangs on readLine()
- Server runs second, hangs on readLine()
- Confirm to us that you have sprinkled debug statements in the code or have some other way to tell you how far it is getting before hanging

CajunBill
PS - since both endpoints are in the same machine right now, the firewall should not be a problem.  But is it an external firewall or is it a program that runs on the server, such as ZoneAlarm?
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13756008
Firstly, it's Sygate Personal Firewall.. However, I just thought to check the logs, and I've also added a rule, to allow all local traffic on port 9090 (the port that I'm using for this).. So, I now doubt that the firewall is doing anything - but it would be the biggest pain if it is, because my machine is the ICS host, so I can't afford to turn off the firewall. :(

Anyway, back to it:
Yes, I have a way of finding out where exactly it is: my GUI's JLabel 'status' component changes, to tell me what it's done so far, e.g. for the Server:

Waiting for client connection . . .
Client has connected.
Creating secondary connection . . .
Secondary connection created.
Authenticating client . . .

That's where it gets up to.. this is actually the point where the server should be reading for the password and a few other configs from the client.
The client would then write the password, etc, to the server, and then start to read(), and block until any data arrives (but a timeout exception of 20 seconds keeps occuring).

I've also set it, so that once the server recieves any data from the client, then it outputs it to the command line. But, obviously, it doesn't ever do this, because it doesn't get past the read() statement.

Surely there's something wrong with my read() method?!? :o\

Best Regards;
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 13760269
>> I've temporarily removed the setSoTimeout() calls.

Better not to set it :)

>> I've initialized the PrintWriter and BufferedReader from outside the read() and write() methods

Can you post the updated code (where you initialize them, and how you have defined the read () and write () methods)?
0
 
LVL 7

Expert Comment

by:CajunBill
ID: 13762453
I second mayaneagle's request for more information.
What I hope you will provide is the code that you use to set up the sockets.

My suspicion at this point is that the problem is in the subtle details of the sockets, not in the read routine itself.
CajunBill
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13763700
Sure.
I'm actually making two connections between the Server and Client, both on different ports; lol, I'm sure you're thinking that they're probably reading and writing from different ports, but I've checked this, and I'm confident that this is not the case! :) lol

Okay, I'm doing the following (excluding everything unecessary):


// Server Application

private   Socket               sock1              = null;      // Class instances
private   Socket               sock2              = null;      //
private   PrintWriter         wr                  = null;      //
private   BufferedReader  rd                   = null;      //
...
sock1 = createServer( port, 0 );
sock2 = connectTo( sock1.getInetAddress().getHostName(), port+1 );
wr = new PrintWriter( sock1.getOutputStream(), true );
rd = new BufferedReader( new InputStreamReader( sock1.getInputStream() ) );
String auth = read();             // It doesn't pass here
System.out.println( auth );
write( "g" );
...

// Client Application

private   Socket               sock1              = null;      // Class instances
private   Socket               sock2              = null;      //
private   PrintWriter         wr                  = null;      //
private   BufferedReader  rd                   = null;      //
...
String server = "servername";      // this string is actually retrieved from a JTextField
sock1 = connectTo( server, port );
sock2 = createServer( port+1, timeout );    // timeout is currently 0
wr = new PrintWriter( sock1.getOutputStream(), true );
rd = new BufferedReader( new InputStreamReader( sock1.getInputStream() ) );
...
write( password + ":" + res );    // 'res' is an integer
String response = read();          // It doesn't pass here
System.out.println( response );



Then, for the method calls that I've made in those codes, here they are:


private Socket createServer( int port, int timeout )
        {
            try
            {
                ServerSocket srv = new ServerSocket( port );
                if ( timeout > 0 )
                    srv.setSoTimeout( timeout * 1000 );
               
                return srv.accept();
            } catch ( InterruptedIOException ioe )
            {
                setStatus( "Secondary Connection Timeout error has occured." );
                ioe.printStackTrace( System.out );
                error( "Timeout error", "The server failed to respond with a Secondary connection within " + timeout + " seconds." );
                System.exit( -1 );
            } catch ( Exception e )
            {
                setStatus( "Secondary Connection Error has occured." );
                e.printStackTrace( System.out );
                error( "Connection error", "An error occured while creating a Server Socket on port " + port );
                System.exit( -1 );
            }
            return null;
        }
       
        private Socket connectTo( String server, int port )
        {
            try
            {
                return new Socket( InetAddress.getByName( server ), port );
            } catch ( Exception e )
            {
                setStatus( "Connection Error has occured." );
                e.printStackTrace( System.out );
                error( "Connection error", "An error occured while attempting to connect to server." );
                System.exit( -1 );
            }
            return null;
        }


And you've seen the read() and write() methods (previously).

lol.. I would post all of my code, but there's a *lot*, and at least to anyone else, it truly is spaghetti! ;-P

Thanks very much for sticking with this guys, I really appreciate it. Regards;
0
 
LVL 7

Expert Comment

by:CajunBill
ID: 13766507
Are you using MX4J ?
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13766533
> Are you using MX4J ?
I don't know what that is, so that'll be a "no" ;)
0
 
LVL 7

Assisted Solution

by:CajunBill
CajunBill earned 800 total points
ID: 13768374
OK, IM,
Just quickly without running the code myself, it looks like one or the other of Client or Server must be catching an exception and returning a null.
Let's say you run Server first - then when it tries to connect to the port from the client, it cannot, since it is not created yet.
If you run Client first, then it cannot connect to the server port, because that port is not created yet.
It looks like a form of "race condition" to me.
You can fix that by having Server start first, then have server kick off the Client process, then wait a few seconds or wait for some flag or other indication from Client, before trying to connect to the client's port.
HTH
Bill
0
 
LVL 30

Accepted Solution

by:
Mayank S earned 800 total points
ID: 13769393
Why are you calling createServer () at both the places, even at the client? I would write a client/ server this way:

public class Server
{
  public static void main ( String[] args )
    throws Exception
  {
    ServerSocket ss = new ServerSocket ( 2725 ) ;
    while ( true )
    {
      new ServerThread ( ss.accept () ) ;
    }
  }
}

class ServerThread extends Thread
{
  private Socket s ;
  private BufferedReader br ;
  private PrintWriter pw ;

  public ServerThread ( Socket s )
    throws Exception
  {
    this.s = s ;
    br = new BufferedReader ( new InputStreamReader ( s.getInputStream () ) ) ;
    pw = new PrintWriter ( new PrintWriter ( s.getOutputStream (), true ) ) ;
    start () ;
  }    
 
  public void run ()
  {
    while ( true )
    {
      // read messages from the client using br.readLine () and process them
      // send messages to the client using pw.println ()
    }
  }
}

The client would just open a socket using:

Socket s = new Socket ( "IP of server", 2725 ) ;
BufferedReader br = .... ; // similar to above
PrintWriter pw = ....

Use pw.println () to send messages to the server and br.readLine () to read messages
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13801805
Thanks all.
0
 
LVL 92

Expert Comment

by:objects
ID: 13802660
no worries :)
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

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

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…
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…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
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 Month18 days, 8 hours left to enroll

825 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