Java server/client application only displays messages upon pressing enter - java

Server Side:
try {
ServerSocket server_socket=new ServerSocket(port_number);
Socket client_socket= server_socket.accept();
PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true);
BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in));
String userInput, clientOutput;
while ((userInput=stdIn.readLine())!="EXIT") {
if ((clientOutput=input.readLine())!=null) {
System.out.println("Client: "+clientOutput);
} if (userInput!=null) {
output.println(userInput);
output.flush();
}
}
}
Client Side:
try {
Socket client_socket= new Socket(hostname,port_number);
PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true);
BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in));
String userInput,serverOutput;
while ((userInput=stdIn.readLine())!="EXIT") {
if ((serverOutput=input.readLine())!=null) {
System.out.println("Server: "+serverOutput);
} if (userInput!=null) {
output.println(userInput);
output.flush();
}
}
}
The code in my case makes sense to me, I cant seem to figure out why an enter still needs to be pressed, does it have something to do with .readLine()?
I checked out the following post Server Client in Java only displays message when I press enter, however the solution provided does not fix the situation.
Note: Initially there were no if statements in the while loop. The way I saw this to be an issue was that the while loop may get stuck on one of the lines, waiting for user/server input. Therefore implementing if statements allowed it to skip the waiting portion and re-run the loop.

Turns out I mixed my variables up.
The while loops should be:
while ((userInput=input.readLine())!="EXIT") {
It fixed it, but there are some other issues still present

does it have something to do with .getLine()?
Yes. If you look at the Javadoc for BufferedReader#readLine(), it clearly states that an end of line character terminates the String to be read:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

Related

ObjectInputStream.readObject skips last line of text file

Fairly simple question, I have a server with some file, lets call it serverFile.txt and I wish to send it line by line to some client. to achieve this, i wrote this simple code on the server side
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
while(line != null)
{
line = line + System.lineSeparator();
MMULogFileController.getOos().writeObject(line);
line = br.readLine();
System.out.println(line);
}
br.close();
where the MMULogFileController.getOos is the outputstream of the accepted socket.
It does indeed print all the lines of the file serverFile.txt
My problem is on the client side. This is the relevant code -
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
String line = (String)in.readObject();
File newLogFile = new File("newLog.txt");
PrintWriter ptofile = new PrintWriter(newLogFile.getName());
while(line != null)
{
ptofile.write(line);
try
{
line = (String) in.readObject();
}
catch(java.io.EOFException e)
{
line = null;
}
}
ptofile.close();
and it prints all the lines correctly into a new file on the client side, except for the very last line. I know it was sent from the server because it was printed, but on the client side it recieved null because it reaches EOF. Is there any way to deal with this?
Myself, I'd use a PrintStream to send the text out, and then read it in using either a BufferedReader or a Scanner. But having said that, if you insist on using an ObjectOutputStream, you should either flush or close it when done sending your file's text, and certainly close it when you're done using it.
Also, avoid this type of code:
catch(java.io.EOFException e)
{
line = null;
}
since this means that you're completely ignoring your exceptions. At least view the stack trace.

How to use BufferedReader correctly with sockets

The application is a basic chat client.
I got a Thread for getting data from the server.
I want to get every response from the server separately.
It prints in the console only when the loop breaks (when i send "exit" using the other parts of the application).
So when "System.out.println" responds it prints the whole buffer at once.
How can i make it work and print every response separately?
Thank you!
EDIT!!
The server respond should include "\n" after each line,
it works for me in this way.
Without "\n" it just waits until the loop breaks.
Is there a better way to do this without the "\n" issue?
class ServerThread implements Runnable {
#Override
public void run(){
BufferedReader in = null;
Socket socket;
try
{
if (Thread.currentThread().isAlive()) {
sendString("exit");
Thread.currentThread().interrupt();}
InetAddress serverAddress = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddress, SERVER_PORT);
outr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String serverResponse;
while((serverResponse = in.readLine()) != null)
{
System.out.println(serverResponse);
}
in.close();
outr.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
You're using a BufferedReader and read it with in.readLine(), which, surprise surprise, will return the next line in the response. A line is a string terminated by a newline character, so your BufferedReader will have to wait until it sees a newline until it can return your line. If you don't want to use newlines in your response, don't use readLine(), use one of the other read() methods instead.

Why can my program only get half of the standard input from pipe?

If I get the standard input from pipe like this, it is ok.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while((input=reader.readLine())!=null)
{
...
}
But if I write my program like this,the BufferedReader can only get a half standard input from the pipe. The pipe will stop somewhere but the position is not certain.
And also every time I input manually line by line. The program is fine. But if I suddenly input a thousand lines. It will only output the result of the first line. I used to input only manually before so this is the first time I met this problem. I thought this two should be the same.
while(true)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
if((input=reader.readLine())==null)
{
break;
}
...
}
The BufferedReader will read more than one line, so the next invocation can get more data without going through the operating system, which enhances performance.
If you delete the BufferedReader and create a new one, all the data that is already stored in the first instance is lost.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input;
String completeInput = "";
while(true)
{
if((input=reader.readLine())==null)
{
break;
}
//here you need to do something with your input
//for example
completeInput+=input;
}
//here you have complete input string in complete input
The difference between these 2 ways of coding is very simple.
First way:
you have declared buffer reader outside the while loop like below
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
and hence for each iteration of while loop, it keeps pointing to the single same console
and hence it reads all data from the console so is the output in right way as expected
second way:
you have declared buffer reader inside while loop like below
while(true)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//rest of the code
}
here for each iteration it creates new reader pointing to new console because of System.in assigned to reader for every while loop iteration.
so when it reads first time it reads all your lines and execute else block and prints first line because of readLine method gets only one line at a time.
and during second iteration of while loop , it points to new console and new console will not have any data so it breaks the while loop.
but if you enter line by line each while loop iteration points to new console and you enter it to new console each time and hence it prints correctly.

Chat client only printing 1 line at a time

I am writing a multithread chat server/client, I have been using SocketTest V 3 to test the server and it seems to be working fine but the client I have written only updates in the console when I write a new line, I am using my own client up against the socket test, and the socket updates every time something is written but my client does not
public class clientV2 {
public static final int PORT = 5019;
public static InetAddress host;
public static void main(String[] args) throws IOException {
try {
host = InetAddress.getLocalHost();
Socket socket = new Socket(host, PORT);
Scanner in = new Scanner(System.in);
Scanner inputFromServer = new Scanner(socket.getInputStream());
PrintWriter outputToServer = new PrintWriter(socket.getOutputStream());
while(true) {
if(inputFromServer.hasNext()) {
System.out.println(inputFromServer.nextLine());
}
String input = in.nextLine();
outputToServer.println(input);
outputToServer.flush();
}
} catch (Exception e) {
}
}
}
Your client calls nextLine() on its scanner, and this method, as it names indicates, returns the next line. So your client can't print anything until the complete next line is available.
Here's what the javadoc says about nextLine():
Advances this scanner past the current line and returns the input that
was skipped. This method returns the rest of the current line,
excluding any line separator at the end. The position is set to the
beginning of the next line.
Since this method continues to search through the input looking for a
line separator, it may buffer all of the input searching for the line
to skip if no line separators are present.
This is because System.out.println(inputFromServer.nextLine()); does exactly that. It waits for a full line and then prints that out. It will not print partial lines.
If the output is missing more than just the last partial line (line-break to line-break; line wraps don't count), look for the buffers along the way.
You can use an InputStreamReader to read single characters from the input stream (which is a byte stream). You can specify the charset in the constructor.
InputStreamReader inputFromServer =
new InputStreamReader(socket.getInputStream(), "UTF-8");
System.out.print((char) inputFromServer.read());

Java Server reply is not printed as expected

I am building a simple client-server program , I have in main :
FTPClient ftp = new FTPClient("www.kernel.org");
ftp.getReply();
ftp.sendCommand("USER " + "anonymous");
ftp.getReply();
ftp.sendCommand("PASS " + "anonymous");
ftp.getReply();
String com="";
while (!com.equalsIgnoreCase("quit")){
System.out.println("Enter your Commands . or Enter quit");
BufferedReader Keyboard = new BufferedReader(new InputStreamReader(System.in));
com = Keyboard.readLine();
ftp.sendCommand((com));
ftp.getReply();
System.out.println("===============");
}
ftp.close();
the problem is in the getReply() function, this function is :
public void getReply() throws IOException {
String line="";
while (br.ready())
{
line = br.readline();
System.out.println(line);
System.out.flush();
}
}
br is a BufferedReader.Now all the problem is that when the program starts it doesn't show the welcome message from the Server until I press Enter or any command, when I Debug the program Step by Step every thing is working perfectly.So is the problem in the readline and I should use something else or what?
The problem is likely that the end of the server response does not contain a newline character. The BufferedReader's readLine method will block until a line of data is received, where "a line" consists of some characters followed by a newline character (or the end of the stream). Consequently, the readLine call will not return if no newline is received.
In this situation then, the BufferedReader isn't doing you any good. You'd be better off using the underlying Reader yourself, reading into an array and emitting the output as soon as it comes in, such as the following:
final char[] buffer = new char[256]; // or whatever size you want
int nRead;
while ((nRead = reader.read(buffer)) != -1)
{
System.out.println(new String(buffer, 0, nRead));
System.out.flush();
}
The condition in the while loop there might look confusing if you're not used to it before, but it combines the read operation (which reads into the buffer) with the check that the end of the stream has not been reached. Likewise, the construction of the String within the while loop takes into account the fact that the buffer may not have been filled entirely, so only as many characters as were supplied are used.
Note that this particular snippet keeps looping until the stream is empty; you may wish to add another exit condition in your particular case.

Categories

Resources