Android Java - Two socketmessages when sending one - java

I send a message over sockets from an android app to a java program. This message is sent with a printwriter.
here is how I send my message from android to java program:
out.println("Hello there");
out.flush();
This is how I receive the message:
while(true){
String msg = in.readLine();
System.out.println("MSG: " + msg);
...some if-statements...
}
The output of the System.out.println is:
MSG: Hello there
*MSG: null*
How come I get null there? I'm only sending "hello there"..
Help would be appreciated, thanks!
EDIT: Actual code of the java program.
while (run) {
String msg = in.readLine();
String[] parts;
String username;
String password = null;
System.out.println("MSG: " + msg);
parts = msg.split("\\*");
username = parts[0];
password = parts[1];
boolean validUser = false;
validUser = db.authenticate(username, password);
if (validUser) {
db.updateIP(username, socket.getInetAddress().getHostAddress());
out.println("done");
out.flush();
} else {
out.println("loginfail");
out.flush();
closeSocketConnection();
}
}
}
private void closeSocketConnection() throws IOException {
in.close();
out.close();
socket.close();
run = false;
}

What is your exit condition for your while loop?
It looks to me like it is repeating and readLine will return null when the end of the stream has been reached causing MSG: null to be printed.
Updated given new information:
Assuming user*123 is a valid username/password combo then closeSocketConnection() is never called, the loop returns to the top, readLine returns null and you see your erroneous output. Followed by a NullPointerException on parts = msg.split("\\*");

Your loop should read:
while ((line = in.readLine()) != null)
{
// ...
}
At the moment you're processing the null that indicates end of stream inside the loop, hence you're printing it as a message when it isn't.

Related

Messages sent over socket not being printed on the receiving side

I am currently learning Java, and I tried to make a simple chat program, which communicates between a server and a client. My problem is that the two programs connect properly to each other, but send messages do not get print out. I do not know whether it is the sending or receiving part. Do not judge my class naming, it is just temporarily.
The client-side part of receiving:
InputStream is = chatterSock.getInputStream();
OutputStream os = chatterSock.getOutputStream();
Thread readThread = new Thread(() -> {
while (true) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
chatter.print("<p>" + out.toString() + "</p>");
} catch (IOException ex) {
chatter.printWarning("Connection lost");
}
}
The server-side part is pretty similar.
To send messages I just run
<Socket>.getOutputStream().write(<String>.getBytes());
I already tried some other posts from stackoverflow, but did not find a way that works. Thanks for your help!
Edit: here is the server side:
InputStream is = chatterSock.getInputStream();
OutputStream os = chatterSock.getOutputStream();
Thread readThread = new Thread(() -> {
while (true) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
overlord.print("<p>" + out.toString() + "</p>");
} catch (IOException ex) {
overlord.chatterSockList.remove(overlord.chatterSockList.indexOf(chatterSock));
overlord.printWarning("Connection to " + chatterSock.getInetAddress() + " lost");
overlord.sendToAll(("User " + username + " disconnected."));
}
}
});
Edit: The message gets send here:
sendButton.addActionListener(e -> {
try {
chatterSock.getOutputStream().write((messageArea.getText()+"\n").getBytes());
messageArea.setText("");
} catch (IOException ex) {
System.err.println(ex);
printWarning("Connection lost"); //TODO heartbeat
}
});
As #Russell Uhl mentions in his comment, a read loop whose termination condition is reader.readLine()) != null is only going to terminate when the output stream is closed.
If the output stream is not closed, that call simply waits for new information, and shall continue to do so indefinitely.
It is also going to wait indefinitely if you don't send over a newline, which is why you were told to add it to your write command.
It would be best to process each line you read separately, rather than trying to append them to a buffer and output them all together. Do the processing inside the loop.
And probably it's also a good idea to add some button to your GUI to terminate the chat. It will disable the rest of the GUI and close the output stream, which in turn will cause the readLine() to return null, and the loop to terminate properly.

(Sockets) In java program pop3 commands only retrieve one message

I wrote a java program without the javax.mail package. To connect to my Gmail account I am using socket. To retrieve my messages I'm using a for loop.
for(int i=1; i<=NumOfMsg; i++){
output.println("RETR "+i);
do{
answer = response();
System.out.println(answer);
}
while (true);
response is method which look :
String response() throws IOException {
response = input.readLine();
if(response == null)
return null;
else
return answer;
}
When this program is conducted it only returns the first letter. After that the program won't repeat the loop. Cursor is blinking and I can't understand is he waiting another input of retr hanging. If I leave the program for 5 minutes it's starting eternal cycle and prints null.
Any suggestions would help.
Your logic is incorrect. You assign answer to the first result from response(), and then never update it, unless the response is null.
If you want to build an answer from the response, you should have a loop that appends the response to the answer variable.
for(int i = 1; i <= NumOfMsg; ++i){
output.println("RETR " + i);
do {
answer = response();
System.out.println(answer);
}
while (true);
}
String response() throws IOException {
response = input.readLine();
return response == null ? answer : answer + response;
}

Text being lost in transmit in chat client

I have a Java Client/Server chat application and after a connection gets established, only about 1 quarter of the data is being received by the recipient. What could the problem be? Here is a print screen of what happens exactly:
Code for reading from socket:
public void somethingElse(){
try {
if(in.readLine() != null){
messageBufferIn = in.readLine();
System.out.println(in.readLine());
chat.append(recipient + ": " + messageBufferIn + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
Code for thread that runs above method:
public class chatListener extends Thread{
static main main = new main();
//static Thread mainThread = new Thread(main);
public void run(){
while(main.isConnected == true){
main.somethingElse();
}
}
}
The above thread gets run as soon as a connection gets established
Thanks for any help
Each time you call in.readLine, the scanner moves down to the next line; you can't keep calling it a few times, as it will skip the lines you never used essentially. Try this to replace somethingElse():
public void somethingElse(){
try {
String line;//Added a variable to store the current line to; readLine is
//dynamic, it returns the next line each call, so if we store to a variable,
//we only call it once, and hold that value
if((line = in.readLine()) != null){// (line = in.readLine()) != null is shorthand to store readLine to line, and then check if that returned value is null or not
System.out.println(line);//Print out the line
chat.append(recipient + ": " + line + "\n");//Append it
}
} catch (IOException e) {
e.printStackTrace();
}
}
Before, you were calling in.readLine once to check if it was null, then you saved the next line, then printed the next one. Hence the pattern of (fail success fail | fail success fail etc.) = Only messages 2 + 5 showing up

Socket, BufferedReader hangs at readLine()

I have a server which initially does this:-
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
for (;;) {
String cmdLine = br.readLine();
if (cmdLine == null || cmdLine.length() == 0)
break;
...
}
later it passes the socket to another class "foo"
This class wait for application specific messages.
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
appCmd=br.readLine();
My client sends this sequence:
"bar\n"
"how are u?\n"
"\n"
"passing it to foo\n"
"\n"
The problem is that sometimes "foo" does not get its response. It hangs in the readLine().
What is the chance that readLine() in the server is buffering up the data using the read ahead and "foo" class is getting starved?
If I add a sleep in the client side, it works. But what is the chance that it will always work?
"bar\n"
"how are u?\n"
"\n"
sleep(1000);
"passing it to foo\n"
"\n"
How to fix the problem? Appreciate any help on this regard.
eee's solution works perfectly. I was trying to read output from an SMTP conversation but it would block on:
while ((response = br.readLine()) != null) {
...Do Stuff
}
Changing to:
while (br.ready()) {
response = br.readLine();
...Do Stuff
}
I can read everything just fine. br is a BufferedReader object, BTW.
There is data already in the first BufferedReader (that has been read from the socket, and is no longer available from the socket), so pass the BufferedReader created in the first example to the class that reads the app specific messages, rather then creating a new BufferedReader from the socket.
I had the same problem and here is my solution:
try {
StringBuilder response = new StringBuilder();
response.append("SERVER -> CLIENT message:").append(CRLF);
//Infinite loop
while (true) {
//Checks wheather the stream is ready
if (in.ready()) {
//Actually read line
lastLineFromServer = in.readLine();
//If we have normal behavior at the end of stream
if (lastLineFromServer != null) {
response
.append(lastLineFromServer)
.append(CRLF);
} else {
return response.toString();
}
} else {//If stream is not ready
//If number of tries is not exceeded
if (numberOfTry < MAX_NUMBER_OF_TRIES) {
numberOfTry++;
//Wait for stream to become ready
Thread.sleep(MAX_DELAY_BEFORE_NEXT_TRY);
} else {//If number of tries is exeeded
//Adds warning that things go weired
response
.append("WARNING \r\n")
.append("Server sends responses not poroperly.\r\n")
.append("Response might be incomplete.")
.append(CRLF);
return response.toString();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
The answer might be late but this is the simplest and latest answer in 2020, just use the simple way to receive the data from the socket server or client using the input stream read() method.
EOFException will be thrown when the client is disconnected or the server closed the connection.
private String waitForData() throws IOException {
String data = "";
do {
int c = inputStream.read();
if (c > -1) data += (char) c;
else throw new EOFException();
} while (inputStream.available() > 0);
return data;
}

it doesn't return anything from server!

I have 2 important classes(client and server) and I will write something in my text area and by clicking on the send button I will call the active method of the client class and I will send that text to my client class,every thing is ok and that text also will be printed on the server console but I can not echo that text from server to client,please help me thanks.
client class:( a part of that)
os = new PrintWriter(c.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(c.getInputStream()));
public static void active() {
String teXt = MainClient.getText();
os.println(teXt);
String line = is.readLine();
System.out.println("Text received: " + line);
os.flush();
is.close();
is.close();
c.close();
server class:( a part of that)
BufferedReader streamIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter streamOut =new PrintWriter(client.getOutputStream());
boolean done = false;
String line =null;
while (!done ) {
line = streamIn.readLine();
if (line.equalsIgnoreCase("bye")) {
done = true;
} else {
System.out.println(line);
streamOut.println(line);
}
}
streamIn.close();
client.close();
server.close();
actually Nettogrof is going the correct way, but you must also flush the server side:
line = streamIn.readLine();
if (line.equalsIgnoreCase("bye")) {
done = true;
} else {
System.out.println(line);
streamOut.println(line);
streamOut.flush(); // or ...checkError();
}
or just create the PrintWriter with autoFlush set to true:
PrintWriter streamOut = new PrintWriter(client.getOutputStream(), true);
One note: you should also test if readLine() is returning null since the client will close the connection without sending a "bye".
A second note: instances of PrintWriter never throw IOExceptions, you should test for errors calling checkError(), which also flushes the stream.
You need to " os.flush(); " before reading the server answer.
Because according to your client code, you prepare the text to send with
String teXt = MainClient.getText();
os.println(teXt);
Then you wait for server answer by :
String line = is.readLine();
System.out.println("Text received: " + line);
Then you send your text to the server :
os.flush();
try :
String teXt = MainClient.getText();
os.println(teXt);
os.flush();
String line = is.readLine();
System.out.println("Text received: " + line);
Your server code implementation is wrong, streamIn,client and streamOut are never closed because of infinite loop.
Refer article mentioned by medopal for more help.
How frequently is the input stream being read? From the code, it looks like there is a single read, probably before anything has been sent from the server, and that's it. You'll probably have to do more consistent polling of the server if you're going to to use the approach you've taken.
Something like:
while (line = is.readLine() != null ) {
System.out.println("Text received: " + line);
}

Categories

Resources