InteractiveMind
asked on
Unexpected timeout error
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
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
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I would use a PrintWriter too, with flush on new-line set to true:
PrintWriter pw = new PrintWriter ( sock.getOutputStream (), true ) ;
pw.println ( str ) ;
PrintWriter pw = new PrintWriter ( sock.getOutputStream (), true ) ;
pw.println ( str ) ;
ASKER
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;
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;
At the client, are you calling the setSoTimeout () method on the socket anywhere?
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.
ASKER
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.
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.
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?
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?
ASKER
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;
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;
>> 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)?
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)?
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
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
ASKER
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().get HostName() , 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;
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().get
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;
Are you using MX4J ?
ASKER
> Are you using MX4J ?
I don't know what that is, so that'll be a "no" ;)
I don't know what that is, so that'll be a "no" ;)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks all.
no worries :)
Perhaps it is because Client is not writing an end of line??
HTH
Bill