• Post Reply Bookmark Topic Watch Topic
  • New Topic

Trouble using BufferedReader and the If Else statement.  RSS feed

 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone!

I'm trying to make a simple TCP server. It works great, except for one bit; the command recognition. I'll show you my code:


All other code works perfectly and should not influence this behaviour.

The problem is that the if{}else if{}else{} statement always picks the else{}, no matter what command is. The System.out.println(command) even gives "EHLO" as output when I telnet "EHLO blahblah" to the server, so it should work.
However it does not. It always displays that the command was not recognized.

Is there something I should know about BufferedReader's behaviour in String comparisons? I've tried everything already!
 
Koen Aerts
Ranch Hand
Posts: 344
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try "EHLO".equals(command) instead.
 
William P O'Sullivan
Ranch Hand
Posts: 859
Chrome IBM DB2 Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
String comparison!!!

Do not use "=="

Use:

WP
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You guys are amazing! I had become way too used to PHP apparently, where this is a very usual thing to do. ;P

Thanks!
 
Koen Aerts
Ranch Hand
Posts: 344
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I like to put hardcoded strings first, so that you can avoid nullpointer exceptions. For instance instead of stringValue.equals("HI") I would do "HI".equals(stringValue). If stringValue == null, then the first example will throw an exception, while the latter will just return false.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I ran into a new problem, that is slightly different, but relatable.

When a user inputs its command, like EHLO, but does it wrong, he'll have to backspace. Now here's the problem; an EHLO is, according to java, not the same as EFK[backspace][backspace]HLO. How do I parse or convert the string in such a way that the backspaces will be removed, or let the if statement ignore the backspaces, or implement them correctly.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you ask that because you are actually getting such strings in your input stream? I don't know anything about your input stream or where it's getting its data from, but I would be surprised if you actually have that problem to deal with.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, the code is for a server that responds to Telnet connections.
So yes, when a user types something wrong, the backspace must function properly or otherwise its command won't be recognized.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay. I'll assume that was meant to answer my question and that the answer was "yes", then. So: what character are you seeing in your command variable which corresponds to a backspace?
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I hope this is what you meant.

It doesn't appear in the command prompt, neither in the client's or in the server's. Very strange. Actually not that strange at all, though I'm looking for a way to remove those special invisible backspace characters and output the right string.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, that wasn't what I meant. What I meant was this: The first character is "E". The second character is "G". The third character is ___, representing the backspace the user pressed. The fourth character is "H". And so on.

You can use the toCharArray() method to get an array of chars from a String. Convert each of the chars to a Unicode code-point by casting it to int.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And with that I remove backspaces, or show you what a backspaced string looks like?
If that latter, visualize it as "EH\bHLO" where \b is the backspace. Eclipse shows me this in its console:
If the first, you'll have to go more into depth with that, as I completely do not understand what I'm supposed to do with an array of integer values.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Never mind, I wrote a method that removes the backspaces and the character before the backspace. Here's the code:
 
Koen Aerts
Ranch Hand
Posts: 344
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What if the first character is a backspace?
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You'll get an ArrayOutOfBounds exception.. ;D Easily fixed though:
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Koen Aerts wrote:I like to put hardcoded strings first, so that you can avoid nullpointer exceptions. For instance instead of stringValue.equals("HI") I would do "HI".equals(stringValue). If stringValue == null, then the first example will throw an exception, while the latter will just return false.


On the other hand, if it's not valid for stringValue to be null at that point, it's better to to stringValue.equals("HI") so that you get the NPE instead of hiding the bug.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's true, and because it's all in an try catch anyway, the program will not crash into a runtime error.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not sure I follow your logic there, Casper. Last time I checked, NullPointerException was indeed a RuntimeException. And maybe your definition of "crash" is different from mine, but the program shown above will not handle any exception gracefully.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Uhm I don't know what is then, as the code where the NullPointerException may occur is nicely try-catched and taken into account that the string will always be initialized as "" because it comes from a bufferedreader and in my experiences that always initializes a value, so a NullPointerException is never thrown.
The IOException from the buffered reader is try-catched as well, so the code will continue.

Maybe mu use of runtime error was incorrect, but what I meant was that it won't stop the program because it would be catched.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So what happens in the catch block? You print the stack trace and close the connection. And what happens after that? You go right back into the loop and try to read again. Now, I don't know exactly what closeConnection() really does, but if it does indeed close a connection, and if that connection is what we're reading from in input.readLine() - what's going to happen here? And what's going to happen after that? And again, and again, and again?
 
Koen Aerts
Ranch Hand
Posts: 344
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unless the program throws some sort of java.lang.Error or subclass such as OutOfMemoryError, the program will never end.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Casper Bezemer wrote:That's true, and because it's all in an try catch anyway, the program will not crash into a runtime error.


No. Don't catch NPE. First, catching an exception and then continuing on like nothing is wrong completely defeats the purpose of having exceptions in the first place. Second, NPE indicates a bug in your code, and you should not usually catch it. Instead, you test, and when you see your code blowing up with NPEs, you fix the bug.
 
Casper Bezemer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But you guys don't understand! The try-catch is not for the NPE, it's for the IOException of the BufferedReader. A NPE can never occur in my code as a well executed readLine() will always initialize a string, except if an IOException is given, and then you simply try again. (or close the connection, in my case. Though please forgive me for not ending the loop in my catch, as I wrote the catch before I wrote the loop and started this topic. I fixed it a while ago already.)
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I would argue that there are times when it can be acceptable to catch a general exception type like RuntimeException or Exception (or occasionally even Throwable), log the error, and then try to move on. Mostly this occurs when processing a series of records or requests where (a) you've tested well enough to be reasonably sure that the code will work correctly most of the time, but (b) certain situations may activate unforseen errors, rarely (we hope), and (c) it's reasonably plausible that, whatever may have gone wrong during the processing of record N (or request N), the same situation may well not occur during the processing of record N+1, and there is business value in processing subsequent requests even though something went wrong with one of them. In such cases, it's imperative that we monitor the logs for errors, and fix them - but meanwhile we may still need to be handling new records, requests, etc.

The thing is, whenever we catch any sort of exception, we really have to think about exactly what happens after it's been caught. It's not enough to say it was caught, so it's OK. We have to look at where it was caught, and what code will get called right after that, and whether the code can successfully return to doing something useful. Sometimes, crashing the program is the best thing you can do, as there's no sensible way to proceed. Other times, you can recover (even if it was a programmer error that you still need to fix) - but you have to pay attention to how you clean up the effects of the error, and make sure things are in a state where you can proceed.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Casper Bezemer wrote:But you guys don't understand! The try-catch is not for the NPE, it's for the IOException of the BufferedReader.

Remember, folks above were talking about the possibility of a NullPointerException, and you responded by saying "because it's all in an try catch anyway, the program will not crash into a runtime error. " That's what we're responding to.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Casper Bezemer wrote:But you guys don't understand! The try-catch is not for the NPE, it's for the IOException of the BufferedReader. A NPE can never occur in my code


Okay. I guess I misunderstood when you said, "the code where the NullPointerException may occur is nicely try-catched."
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:Well, I would argue that there are times when it can be acceptable to catch a general exception type like RuntimeException


Hence my use of "usually." It's valid at things like layer boundaries, such as an app server catching unchecked exceptions thrown by one of its apps so that one badly behaved app doesn't necessarily bring down the whole shebang, or in cases where you're doing process(A); process(B); process(C); and you don't want a failure in one to prevent processing of the others.

I don't think the OP is there yet though.

and there is business value in processing subsequent requests even though something went wrong with one of them. In such cases, it's imperative that we monitor the logs for errors, and fix them - but meanwhile we may still need to be handling new records, requests, etc.


Exactly. As long as you're sure that the exception affects only the ting you just tried to process, and won't lead to corruption in subsequent processing.

The thing is, whenever we catch any sort of exception, we really have to think about exactly what happens after it's been caught. It's not enough to say it was caught, so it's OK. We have to look at where it was caught, and what code will get called right after that, and whether the code can successfully return to doing something useful.


Yup. Too many beginners seem to conflate "catching the exception" with "fixing the problem".
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!