How can I detect a carriage return using java.net

Discussion in 'Java' started by Angus, Oct 21, 2006.

  1. Angus

    Angus Guest

    Hello

    I have code a bit like this:

    BufferedReader bis = new BufferedReader(new
    InputStreamReader(tserverSocket.getInputStream()));

    // Here I write some data - getting a response - some lines of text returned

    boolean more = true;
    while(more)
    {
    String line = bis.readLine();
    if (line == null)
    more = false;
    else
    System.out.println(line);
    }

    But code never gets out of while loop.

    I assumed when there was no more input it would return null, so more would
    be set to false and it would exit loop.

    I want to test for a carriage return. (I know text is in ASCII format, and
    I know end of each line has a carriange return and line feed.

    So I tried doing this:

    if (line.indexOf("\n") != -1)
    {
    break;
    }

    But it didn't seem to find \n . How should I test for a carriage return?

    Angus
    Angus, Oct 21, 2006
    #1
    1. Advertising

  2. Angus

    Guest

    Angus,

    BufferedReader does return null when there is more data to read.
    However, when dealing with a socket (based on the "tserverSocket"
    variable name), its possible that if the connection is still active
    that the empty string might be what is being returned. The
    BufferedReader.readLine() method automatically strips off the carriage
    return so trying to match based on that will never be true.

    For example, if the stream sends "one\ntwo\nthree\n" The first
    invocation of readLine() would return "one", etc.

    I think I need a little more information about the tserverSocket to
    assist more on this.


    kavaj

    Angus wrote:
    > Hello
    >
    > I have code a bit like this:
    >
    > BufferedReader bis = new BufferedReader(new
    > InputStreamReader(tserverSocket.getInputStream()));
    >
    > // Here I write some data - getting a response - some lines of text returned
    >
    > boolean more = true;
    > while(more)
    > {
    > String line = bis.readLine();
    > if (line == null)
    > more = false;
    > else
    > System.out.println(line);
    > }
    >
    > But code never gets out of while loop.
    >
    > I assumed when there was no more input it would return null, so more would
    > be set to false and it would exit loop.
    >
    > I want to test for a carriage return. (I know text is in ASCII format, and
    > I know end of each line has a carriange return and line feed.
    >
    > So I tried doing this:
    >
    > if (line.indexOf("\n") != -1)
    > {
    > break;
    > }
    >
    > But it didn't seem to find \n . How should I test for a carriage return?
    >
    > Angus
    , Oct 21, 2006
    #2
    1. Advertising

  3. Angus wrote:
    > boolean more = true;
    > while(more)
    > {
    > String line = bis.readLine();
    > if (line == null)
    > more = false;
    > else
    > System.out.println(line);
    > }
    >
    > But code never gets out of while loop.
    >
    > I assumed when there was no more input it would return null, so more would
    > be set to false and it would exit loop.


    If you want to read one line then use:

    String line = bis.readLine();


    If you want to read multiple lines then your code
    should work even though:

    String line;
    while((line = bis.readLine()) != null) {
    ....
    }

    is the most common way of doing it.

    Note that readLine first return null (EOF) when the socket is
    closed in the other end.

    Arne
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Oct 21, 2006
    #3
  4. On Sat, 21 Oct 2006 16:14:21 +0100, Angus wrote:
    > // Here I write some data - getting a response - some lines of text
    > // returned
    >
    > boolean more = true;
    > while(more)
    > {
    > String line = bis.readLine();
    > if (line == null)
    > more = false;
    > else
    > System.out.println(line);
    > }
    >
    > But code never gets out of while loop.


    That's a complicated way of writing a simple loop. This is the idiom:

    String line;
    while ((line = bis.readLine()) != null) {
    System.out.println(line);
    }

    > I assumed when there was no more input it would return null, so more
    > would be set to false and it would exit loop.


    It will, but "no more input" means "end of file". readLine() returns
    null and the loop will exit when you reach EOF, i.e. when the remote
    *closes* the connection. You won't reach EOF as long as the remote
    keeps the connection open.

    > I want to test for a carriage return. (I know text is in ASCII
    > format, and I know end of each line has a carriange return and line
    > feed.


    readLine() has already tested for newlines and removed them. Each line
    it returns is exactly one whole line.

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Oct 21, 2006
    #4
  5. Angus

    Angus Guest

    Ah OK.

    So what I really want to know is how do I know when server has finished
    sending me data?

    Eg my socket server sends out 1 to many lines of output. How do I know when
    server has finished sending data? Is it possible?

    Or does my server need to somehow send some data which indicates sending has
    finished?

    I have the source code for the server too so I can edit the the way the
    server outputs data if necessary.

    Angus

    "Gordon Beaton" <> wrote in message
    news:453a41e0$0$8091$...
    > On Sat, 21 Oct 2006 16:14:21 +0100, Angus wrote:
    > > // Here I write some data - getting a response - some lines of text
    > > // returned
    > >
    > > boolean more = true;
    > > while(more)
    > > {
    > > String line = bis.readLine();
    > > if (line == null)
    > > more = false;
    > > else
    > > System.out.println(line);
    > > }
    > >
    > > But code never gets out of while loop.

    >
    > That's a complicated way of writing a simple loop. This is the idiom:
    >
    > String line;
    > while ((line = bis.readLine()) != null) {
    > System.out.println(line);
    > }
    >
    > > I assumed when there was no more input it would return null, so more
    > > would be set to false and it would exit loop.

    >
    > It will, but "no more input" means "end of file". readLine() returns
    > null and the loop will exit when you reach EOF, i.e. when the remote
    > *closes* the connection. You won't reach EOF as long as the remote
    > keeps the connection open.
    >
    > > I want to test for a carriage return. (I know text is in ASCII
    > > format, and I know end of each line has a carriange return and line
    > > feed.

    >
    > readLine() has already tested for newlines and removed them. Each line
    > it returns is exactly one whole line.
    >
    > /gordon
    >
    > --
    > [ don't email me support questions or followups ]
    > g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Angus, Oct 21, 2006
    #5
  6. On Sat, 21 Oct 2006 17:30:53 +0100, Angus wrote:
    > So what I really want to know is how do I know when server has
    > finished sending me data?
    >
    > Eg my socket server sends out 1 to many lines of output. How do I
    > know when server has finished sending data? Is it possible?
    >
    > Or does my server need to somehow send some data which indicates
    > sending has finished?


    Yes it's possible, but the solution depends on what happens later.

    If you don't need to keep the connection open, then the server can
    just close it and readLine() will return null, indicating EOF.

    If you need to need continue communicating with the server, then the
    server should send information the client can use to determine where
    the end of the response is. One way is to precede the response with
    the number of lines to expect so the client can count them. Another is
    to send an extra, empty line ("") after the response (assuming that
    can't occur within the response itself), or to mark the final line of
    the response differently from the others in some way.

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Oct 21, 2006
    #6
  7. Angus

    Red Orchid Guest

    "Angus" <> wrote or quoted in
    Message-ID: <ehdhvu$hhf$1$>:

    > Ah OK.
    >
    > So what I really want to know is how do I know when server has finished
    > sending me data?
    >
    > Eg my socket server sends out 1 to many lines of output. How do I know when
    > server has finished sending data? Is it possible?
    >
    > Or does my server need to somehow send some data which indicates sending has
    > finished?
    >


    As I know as,
    'null' do not necessarily indicate that server has finished
    sending data. 'null' may be returned when unexpected
    network error occurs (ex: unexpected connection close).

    Therefore, communication protocol must have an ending
    indicator.

    For example,
    With NNTP, a single period (".") on a line indicates the
    end of sending data.

    With HTTP, an empty line("") indicates it. (Or "Content-Length").

    With a server that sends only one line to a client always,
    "\r\n" will indicate it.

    I think that you have to code a server that send out it.
    Red Orchid, Oct 21, 2006
    #7
  8. Gordon Beaton wrote:
    > If you don't need to keep the connection open, then the server can
    > just close it and readLine() will return null, indicating EOF.
    >

    With all due respect, I think that the connection should always be
    opened and closed by the client: if the server closes the connection you
    have no way of telling if the network broke, the server crashed or if it
    was an intentional "end of dialog" closure.

    > the server should send information the client can use to determine where
    > the end of the response is. One way is to precede the response with
    > the number of lines to expect so the client can count them. Another is
    > to send an extra, empty line ("") after the response (assuming that
    > can't occur within the response itself), or to mark the final line of
    > the response differently from the others in some way.
    >

    A better way is to precede each message with its length, which should be
    either a binary byte or (better) a fixed length character string, e.g.,

    0012Message data

    This way the receiver starts with a fixed length read to get the message
    data length, translates it into an int and then reads that many bytes to
    get the message. If either read gets the wrong number of bytes you know
    there's a problem and you can take corrective action.

    If both client and server send this type of message both can use the
    same error checking and message decoding code with the addition that, if
    the server receives a zero length message when its expecting a message
    length it knows that the client has closed the connection.

    I usually build messages this way, but assemble them from comma
    separated fields. If the client always sends messages consisting of a
    command and an associated value a message might look like:

    0024,STORE,Text to be stored

    While the reply from the server might look like

    0004,OK,

    or

    0023,ERROR,The file is full

    This format has the double advantage that its easy to decode and is
    human-readable when it appears in debugging messages, etc.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Oct 21, 2006
    #8
  9. Angus

    EJP Guest

    wrote:
    >
    > BufferedReader does return null when there is more data to read.
    > However, when dealing with a socket (based on the "tserverSocket"
    > variable name), its possible that if the connection is still active
    > that the empty string might be what is being returned.


    This makes no sense. A null will be returned when the other end closes
    its socket. Anything else returned, including an empty string, is
    returned because the other end wrote it, and for no other reason.
    EJP, Oct 22, 2006
    #9
  10. Angus

    EJP Guest

    Martin Gregorie wrote:
    > With all due respect, I think that the connection should always be
    > opened and closed by the client: if the server closes the connection you
    > have no way of telling if the network broke, the server crashed or if it
    > was an intentional "end of dialog" closure.


    Except that an orderly close returns a null via readLine(), or -1 via
    read(), or an EOFException via any other method, whereas a disorderly
    close throws an IOException, or a SocketException, or possibly just
    blocks forever.
    EJP, Oct 22, 2006
    #10
  11. Angus

    EJP Guest

    Red Orchid wrote:
    > As I know as,
    > 'null' do not necessarily indicate that server has finished
    > sending data. 'null' may be returned when unexpected
    > network error occurs (ex: unexpected connection close).


    This is 100% incorrect.
    EJP, Oct 22, 2006
    #11
  12. On Sat, 21 Oct 2006 22:32:48 +0100, Martin Gregorie wrote:
    > With all due respect, I think that the connection should always be
    > opened and closed by the client: if the server closes the connection
    > you have no way of telling if the network broke, the server crashed
    > or if it was an intentional "end of dialog" closure.


    As EJP already pointed out there are other ways of determining those
    things.

    I wonder though why you want to favour the client. Isn't information
    about the connection state equally useful at *both* ends of the
    connection?

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Oct 22, 2006
    #12
  13. EJP wrote:
    > Martin Gregorie wrote:
    >> With all due respect, I think that the connection should always be
    >> opened and closed by the client: if the server closes the connection
    >> you have no way of telling if the network broke, the server crashed or
    >> if it was an intentional "end of dialog" closure.

    >
    > Except that an orderly close returns a null via readLine(), or -1 via
    > read(), or an EOFException via any other method, whereas a disorderly
    > close throws an IOException, or a SocketException, or possibly just
    > blocks forever.
    >

    If the server crashes when the client is expecting a reply, the client
    will just get a null from readLine because, at the lowest level, the
    reader can't distinguish an intentional close from a connection that
    closes when the remote program crashes.

    IIRC you'll only get the IOException if you try to write to a broken
    connection or try to read it after you've already seen the close.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Oct 22, 2006
    #13
  14. Gordon Beaton wrote:
    >
    > As EJP already pointed out there are other ways of determining those
    > things.
    >
    > I wonder though why you want to favour the client. Isn't information
    > about the connection state equally useful at *both* ends of the
    > connection?
    >

    Yes, of course, but if you use the convention that only the client opens
    and closes connections then:

    - the client can treat any disconnection or i/o problem as an error.

    - the server can always just clean up and wait for another
    connection when it sees a disconnection. It also does the same
    if sending a response fails but should also log the error.

    If the server is stateless that's all it ever needs to do.

    A stateful server is more complex because a disconnect is
    only valid if its waiting for the start of a session. A disconnect
    or i/o error at any other time is always an error.

    I've designed complex, high performance, multi-process systems without
    needing to use stateful message exchanges. These have used
    request/response pairs with the client issuing the request. The overhead
    of the positive response has never been a problem and it certainly makes
    error recovery and process synchronization a lot easier.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Oct 22, 2006
    #14
  15. Angus

    Red Orchid Guest

    EJP <> wrote or quoted in
    Message-ID: <exF_g.51086$>:

    >
    > Red Orchid wrote:
    > > As I know as,
    > > 'null' do not necessarily indicate that server has finished
    > > sending data. 'null' may be returned when unexpected
    > > network error occurs (ex: unexpected connection close).

    >
    > This is 100% incorrect.
    >
    >



    Let's assume that you have an external modem for networking.

    Execute the class 'Test'.
    If you turn off the modem in the middle of receiving data,
    this code returns 'null', not an exception.

    The 'null' do not indicate that a server has finished
    sending data because the modem was turned off.


    <code>
    public class Test {

    public static void main(String[] args) throws Exception {

    process();
    }

    static void process() {
    String url = "http://Your Server/Your Data File";
    BufferedReader br = null;

    try {
    HttpURLConnection uc;

    URL u = new URL(url);
    uc = (HttpURLConnection) u.openConnection();

    int code = uc.getResponseCode();

    if (code != 200) {

    System.out.println("Err Code: " + code);
    return;
    }

    InputStreamReader ir;
    InputStream in;

    in = uc.getInputStream();
    ir = new InputStreamReader(in);
    br = new BufferedReader(ir);

    while(true) {

    if (br.readLine() == null) {

    System.out.println("-< null >-");
    break;
    }
    System.out.println("Receiving ...");
    }
    }
    catch (Exception e) {

    e.printStackTrace();
    }
    finally {
    if (br != null) {
    try {
    br.close();
    }
    catch (Exception e) {
    }
    }
    }
    }
    }

    </code>
    Red Orchid, Oct 22, 2006
    #15
  16. Angus

    EJP Guest

    Martin Gregorie wrote:
    > If the server crashes when the client is expecting a reply, the client
    > will just get a null from readLine because, at the lowest level, the
    > reader can't distinguish an intentional close from a connection that
    > closes when the remote program crashes.


    At the lowest level the TCP stack will receive either nothing or an RST
    from a disorderly close; it will receive a FIN from an orderly close.
    EJP, Oct 22, 2006
    #16
  17. Angus

    EJP Guest

    Red Orchid wrote:
    > If you turn off the modem in the middle of receiving data,
    > this code returns 'null', not an exception.


    Under the rules of TCP/IP you should get either nothing or an
    IOException 'connection reset by peer'.
    EJP, Oct 22, 2006
    #17
  18. EJP wrote:
    > Martin Gregorie wrote:
    >> If the server crashes when the client is expecting a reply, the client
    >> will just get a null from readLine because, at the lowest level, the
    >> reader can't distinguish an intentional close from a connection that
    >> closes when the remote program crashes.

    >
    > At the lowest level the TCP stack will receive either nothing or an RST
    > from a disorderly close; it will receive a FIN from an orderly close.
    >

    Whether that difference is visible at application code level depends on
    the stack implementation. On my kit, like all Unices, the difference
    isn't visible and the behavior is not language dependent: C and Java do
    exactly the same.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Oct 22, 2006
    #18
  19. Angus

    EJP Guest

    Martin Gregorie wrote:
    >> At the lowest level the TCP stack will receive either nothing or an
    >> RST from a disorderly close; it will receive a FIN from an orderly close.

    >
    > Whether that difference is visible at application code level depends on
    > the stack implementation. On my kit, like all Unices, the difference
    > isn't visible and the behavior is not language dependent: C and Java do
    > exactly the same.


    There is no truth in this. At the 'C' level a read() or recv() or
    recvmsg() will return 0 meaning EOF on receiving a FIN, and -1 with an
    errno of ECONNRESET on receiving an RST. This is true both of Berkeley
    Sockets and WINSOCK except for the WSA on the front of the names. At the
    Java level a read() will return -1 on a clean EOF from a FIN, and throw
    an IOException on a reset. Java's readLine(), readObject(), readXXX()
    are all built on read(), and their behaviour on these conditions is
    similarly well-defined.
    EJP, Oct 24, 2006
    #19
  20. EJP wrote:
    > Martin Gregorie wrote:
    >>> At the lowest level the TCP stack will receive either nothing or an
    >>> RST from a disorderly close; it will receive a FIN from an orderly
    >>> close.

    >>
    >> Whether that difference is visible at application code level depends
    >> on the stack implementation. On my kit, like all Unices, the
    >> difference isn't visible and the behavior is not language dependent: C
    >> and Java do exactly the same.

    >
    > There is no truth in this. At the 'C' level a read() or recv() or
    > recvmsg() will return 0 meaning EOF on receiving a FIN, and -1 with an
    > errno of ECONNRESET on receiving an RST. This is true both of Berkeley
    > Sockets and WINSOCK except for the WSA on the front of the names.
    >

    Maybe so for Berkeley Sockets or WINSOCK, but that's not true for the
    version in the Linux Fedora Core distribution. I'm well aware that
    errors cause -1 to be returned, but the stack is not treating the
    disconnection as an error.

    Killing the remote process causes recv() to return zero, exactly the
    same as if the remote process had closed the connection. This is not
    speculation or derived from reading manpages: I just re-checked it by
    running tests.

    As I've seen this behavior in UNIX SVR4 systems as well as Linux its
    obviously not uncommon.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Oct 24, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. michaaal
    Replies:
    21
    Views:
    1,561
  2. thelane
    Replies:
    1
    Views:
    583
    Joseph Kesselman
    Dec 7, 2007
  3. Veronica Bourke

    C# .NET stop carriage return/enter key submitting the form

    Veronica Bourke, Feb 16, 2005, in forum: ASP .Net Web Controls
    Replies:
    3
    Views:
    1,168
    Veronica Bourke
    Feb 16, 2005
  4. Xeno Campanoli
    Replies:
    0
    Views:
    227
    Xeno Campanoli
    Feb 13, 2006
  5. Steve Anderson
    Replies:
    3
    Views:
    248
    Steve Anderson
    Jun 21, 2004
Loading...

Share This Page