Link to home
Start Free TrialLog in
Avatar of lwinkenb
lwinkenb

asked on

problem with I/O

I have a program that reads sends commands to a server, and reads the message back from the server.  The way I have it written now, the code looks like this:

//s is the string to be sent to the server.
//out is a PrintWriter to the sockets OutputStream
//in is a Buffered Reader of the sockets InputStream
if(s != null) {
   System.out.println("C: " + s);
   out.println(s);
   out.flush();
}
String line = in.readLine();
while (line != null) {
   System.out.println("S: " + line);
   line = in.readLine()
}

The way I want the program to work is to send a command to the server, and then read all the lines the server sends back.  The problem is that the program freezes when there are no more lines to be read from the server.

How can I change this so the program knows not to read a line when there is nothing to be read?

Thanks
Avatar of Mick Barry
Mick Barry
Flag of Australia image

The server needs to either close the connection, or send some indication. Otherwise the client has no way of knowing whether the server has more data to send.
Avatar of lwinkenb
lwinkenb

ASKER

I dont have any control over what the server does, I'm only working with the client.  Also, the server doesn't give any indication that the current line would be the last one.

I was thinking of creating a thread to listen for server responses, but Im pretty new to thread programming, and Im not sure if that would work.
If the server provide no indication then there's not much you can do. Just cause there's nothing available to read doesn't mean the servers finished, there may just be network congestion for example.

> thinking of creating a thread to listen for server responses

Unclear how this will help as this is exactly what your curreent thread is doing.
In my case I know the server is finished.

Let's say for example I use the above code to send the "EHLO" command to a smtp server.  The server might respond with

250-smtp.server.com Hello [xxx.xx.x.xx]
250-TURN
250-ATRN
250-SIZE
250-ETRN
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-8bitmime
250-BINARYMIME
250-CHUNKING
250-VRFY
250-X-EXPS GSSAPI NTLM LOGIN
250-X-EXPS=LOGIN
250-AUTH GSSAPI NTLM LOGIN
250-AUTH=LOGIN
250-X-LINK2STATE
250-XEXCH50
250 OK

My program would read in all the lines and display them, and then it would freeze after sending the last line.  Now I could tell my program to stop reading lines after it sees "250 OK", but the server does not respond with "250 OK" as the last line every time it sends something to the client.
> In my case I know the server is finished.

If you know when the server is finished then stop reading.
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
agreed with objects
there has to be some way to determine that server has finished sending the data
in such case u need to change the server response & force it to send 250 OK or some other string to indicate that  it has finished sending data
cheers
RJ
The other option, although it's an ugly one, is to know exactly what the format of any possible message you can receive from the server.  Then, as you receive various messages, you should know what the ending point is for any given message.  Then it's simply a matter of parsing the information as you go to determine what end message you are looking for.
I think it's not an ugly option, it's really what we need to do, understand each response and know where is the end of response.
As in SMTP protocol, here are some notes:
1. 250 OK ends the response and indicate success.
2. DATA response end with a period and then 250 OK.
3. Other codes (not 250) indicate failures and end the response.
You can read more about SMTP protocol at:
http://www.ietf.org/rfc/rfc0821.txt
So all you have to do then is upon reading each line from the server, call some method that checks to see if it's any end response.  Basically, you can do the following:

boolean done = false;
while (line != null && !done)
{
  System.out.println("S: " + line);
  line = in.readLine()
  if (endResponse(line))
  {
    done = true;
  }
}


Then you just have to write the method endResponse to return true when you get an end tag.  Hope that helps.
Hmm...looking closer at what you said I guess you could change the endResponse() method to check that the response is EITHER "250 OK" OR it does not start with "250".  I think that should do what you want shouldn't it?
Ok, looks like I'll just have to look for ways to parse the server's response.  Thanks for the help everyone.

Going to give the points to objects, as he was the first to say that the client could only act on what was being sent by the server.
Have a read of the SMTP protocol:
http://www.ietf.org/rfc/rfc0821.txt

Basically each command sent recieves a reply.
Formally, a reply is defined to be the sequence:  a three-digit code, <SP>, one line of text, and <CRLF>, or a multiline reply (as defined in Appendix E).