Bufferedreader never null, while loop won't terminate - java

I'm making a program where a client uses a proxy to ask a server to retrieve content from an URL, so for example, the client types in "http://www.google.ca", and they get the html code from that webpage. I got it to work once, but I want to it work multiple times. I tried using loops but they never terminate, bufferedreader never seems to = null for the Proxy or Client class (the Server class works fine though). Any help would be greatly appreciated.
Here is my code
Client.java
import java.net.*;
import java.io.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception {
Client serv = new Client();
serv.run();
}
public void run() throws Exception {
Socket sock = new Socket("localhost", 7777); //connects to Proxy
PrintStream ps = new PrintStream(sock.getOutputStream()); //output stream to Proxy
InputStreamReader ir = new InputStreamReader(sock.getInputStream()); //input stream from Proxy
BufferedReader br = new BufferedReader(ir);
Scanner scanner = new Scanner(System.in); //take input from keyboard
//user types in an URL, outputs content of URL
for(int i = 0; i < 100; i++) {
ps.println(scanner.nextLine());
String inputLine;
while((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
System.out.println("DONE");
}
sock.close();
scanner.close();
}
}
Proxy.java
import java.net.*;
import java.io.*;
public class Proxy {
public static void main (String[] args) throws Exception {
Proxy serv = new Proxy();
serv.run();
}
public void run() throws Exception {
ServerSocket ss = new ServerSocket(7777);
Socket sock = ss.accept();
//input and output streams to and from Client
InputStreamReader ir = new InputStreamReader(sock.getInputStream());
BufferedReader br = new BufferedReader(ir);
PrintStream psToClient = new PrintStream(sock.getOutputStream());
//input and output streams to and from Server
Socket sck = new Socket("localhost", 8888);
PrintStream ps = new PrintStream(sck.getOutputStream());
InputStreamReader irFromServer = new InputStreamReader(sck.getInputStream());
BufferedReader brFromServer = new BufferedReader(irFromServer);
//passes message from Client to Server, passes URL content from Server back to Client
for(int i = 0; i < 100; i++) {
String message = br.readLine();
ps.println(message);
System.out.println("Client wants me to tell Server he wants the content of: " + message);
String inputLine;
while((inputLine = brFromServer.readLine()) != null) {
psToClient.println(inputLine);
//psToClient.flush();
System.out.println(inputLine);
}
System.out.println("DONE");
}
sock.close();
ss.close();
sck.close();
}
}
Server.java
import java.net.*;
import java.io.*;
public class Server {
public static void main (String[] args) throws Exception {
Server serv = new Server();
serv.run();
}
public void run() throws Exception {
ServerSocket ss = new ServerSocket(8888);
Socket sock = ss.accept();
//input and output streams to and from Proxy
InputStreamReader ir = new InputStreamReader(sock.getInputStream());
BufferedReader br = new BufferedReader(ir);
PrintStream psToProxy = new PrintStream(sock.getOutputStream());
//retrieves content from requested URL and sends back to Proxy
for(int i = 0; i < 100; i++) {
String request = br.readLine();
System.out.println("Proxy told me Client wants the content from: " + request);
//makes URL object using String value from Client
URL url = new URL(request);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
//sends URL content back to Client, via Proxy
String inputLine;
while ((inputLine = in.readLine()) != null) {
psToProxy.println(inputLine);
//psToProxy.flush();
System.out.println(inputLine);
}
System.out.println("FINISHED SENDING CONTENT");
in.close();
}
sock.close();
ss.close();
}
}

bufferedreader never seems to = null
Your question is a little imprecise. What you mean is that BufferedReader.readLine() never returns null. That only happens when the peer closes the connection. If he never closes it, readLine() won't return null.
If you're writing an HTTP proxy you need to have a good look at RFC 2616, and specifically the requirements about the Content-length header, the Connection: close header, and chunked transfer encoding. Just reading the response stream to its end is in general not sufficient.

Related

TCP client not responding in JAVA

I was learning JAVA networking API and simple TCP server-client communication.
I have written the following two classes for client and server.
The issue is that my client is not responding i.e. the program is not terminating and it doesn't output anything .. Can anyone see where I am going wrong?
Client:
import java.io.*;
import java.net.*;
public class client {
public void go() {
try {
Socket s = new Socket("127.0.0.1",2323);
InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);
String reading = reader.readLine();
PrintWriter write = new PrintWriter(s.getOutputStream());
write.print("mynameistom");
System.out.println(reading);
reader.close();
writeToServer.close();
} catch(IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client;
client.go();
}
}
Server:
package TCP;
import java.io.*;
import java.net.*;
public class Server {
public void go() {
try {
ServerSocket serverSock = new ServerSocket(2323);
Socket socket = serverSock.accept();
InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);
String messsage = reader.readLine();
PrintWriter writer = new PrintWriter(socket.getOutputStream())
writer.println(message);
writer.close();
System.out.println(message);
} catch(IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.go();
}
}
The obvious thing is that the client isn't flushing, and is missing the new line.
PrintWriter writeToServer = new PrintWriter(s.getOutputStream());
writeToServer.print("network");
Should be either
PrintWriter writeToServer = new PrintWriter(s.getOutputStream(), true);
writeToServer.println("network");
or
PrintWriter writeToServer = new PrintWriter(s.getOutputStream());
writeToServer.println("network");
writeToServer.flush();

Socket connection to Heroku java server not working?

I have a simple Java server deployed on Heroku and I want to connect and send strings to and from it using Sockets from a client however I get no response when I send strings.
I have tried changing the port number from 80 to 443.
The server on Heroku:
public class Server {
public static void main(String[] args) throws IOException {
Integer port = Integer.parseInt(System.getenv("PORT"));
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String inputLine;
while((inputLine = in.readLine())!=null) {
out.println(inputLine);
}
}
}
The client on my computer:
public class Client {
public static void main(String[] args) throws IOException {
try {
Socket echoSocket = new Socket("minimal-java-web-app.herokuapp.com", 80);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
String inputLine;
out.println("Sent this message to server");
while((inputLine = in.readLine())!=null) {
System.out.println("got message: "+inputLine);
}
echoSocket.close();
}
I expected an output of "got message: Sent this message to server" in the console when I run the client but I get nothing. No error or server response.

Handler thread hanging on reading in

I am trying to set up a server with a client and a handler. The client should ask for a string from the user. This should then be written to an OutputStream, get read in by the handler which then saves the string to its own OutputStream before passing it back to the client. I know that this program is completely pointless, I am just trying to get my head around how servers, clients and handlers work.
Here is my code so far:
Server
public class Server {
public static void main (String args[]) throws IOException {
int port = 8080;
ServerSocket server = new ServerSocket(port);
while (true) {
System.out.println("Waiting for client...");
Socket client = server.accept();
System.out.println("Client from "+client.getInetAddress()+" connected.");
Handler handler = new Handler(client);
handler.run();
}
}
}
Handler
class Handler extends Thread {
private Socket client;
public Handler(Socket c) {
client = c;
}
public void run() {
try {
Thread.sleep(3000);
System.out.println("1");
PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(client.getInputStream(),
"UTF-8"));
System.out.println("2");
String message = in.readLine();
System.out.println("4");
System.out.println("5");
out.println(message);
out.flush();
client.close();
System.out.println("Finish");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Client
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 8080);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(server.getInputStream(),
"UTF-8"));
out.println(message);
String messageReturn = in.read();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
The problem is that the handler seems to hang when it tries to read the message in. This problem seems similar to the one presented here: Socket problem - readline won't work properly
But this solution isn't working for me. I have tried using objectInputStreams instead of my current solution, but this didn't work either.
I doubt whether your client code will compile. The return type for this is int.
String messageReturn = in.read();
Anyway, this should work:
package network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 9890);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
out.println(message);
// NOTE this
String messageReturn = in.readLine();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
Note Port has been changed.
Server Output
Waiting for client...
Client from /127.0.0.1 connected.
1
Client Output
Attempting connection...
Please enter a string:
Hello
The problem might be that you do not send an escape sequence with your response. ReadLine() waits till it gets an escape. Try sending a "\n" with your response. There is an article about problems using readLine() and println() with sockets. It also shows how to solve it.
ReadLine() / Println() and sockets

Simple client server with loop messaging

I am trying to implement a simple client server program that will continuously exchange messages until client decides to stop. I found many tutorials on this topic, however I am struggling with implementing the loop correctly. The server processes the first request but does not process the others.
It is probably some silly mistake so please excuse me for asking such basic question - I am new to sockets. I would be glad for any help. I provide all the code (based on some example that I found):
Client:
public class Client {
public static void main(String argv[]) throws Exception {
talkWithServer();
}
private static void talkWithServer() throws UnknownHostException, IOException {
String sentence;
String serverResponse;
BufferedReader brClient = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 9000);
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader brServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(true) {
sentence = brClient.readLine();
out.writeBytes(sentence + '\n');
serverResponse = brServer.readLine();
System.out.println(serverResponse);
if (serverResponse.contains("<BYE>")) {
break;
}
}
clientSocket.close();
}
}
Server:
public class Server {
public static void main(String args[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9000);
Protocol protocol = new Protocol();
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
String response = protocol.processInput(clientSentence);
outToClient.writeBytes(response + '\n');
}
}
}
Protocol:
public class Protocol {
public String processInput(String theInput) {
String theOutput = "> " + theInput;
return theOutput;
}
}
I simplified the example for sake of easier debugging. Thanks for any tips!
My guess is line "Socket connectionSocket = welcomeSocket.accept();"
If I remember right, this will try to accept new client everytime, and since you are connecting just one, it will wait on that line forever in second iteration.
I suggest you paste that line before the while loop.
Try below
Socket connectionSocket = welcomeSocket.accept();
while (true) {
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
String response = protocol.processInput(clientSentence);
outToClient.writeBytes(response + '\n');
outToClient.flush();
}

While loop fails when socket reading input in java

so I am having an issue with reading input from a client. It works completely fine whenever I am using my if statements without the while statements wrapped around it in the server class. Could anybody point me to why this may be failing?
Server class:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
//Confirms that the message was received
System.out.println(message);
//When this while is here. The match fails and it goes to the else statement.
//Without the while statement it will work and print "Received our hello message."
//when the client says HELLO.
while(message != null)
{
if(message.equals("HELLO"))
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Received our hello message.");
}
else
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Did not receive your hello message");
}
}
}
}
Client class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Client myClient = new Client();
myClient.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 9999);
//Sends message to the server
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
Scanner scan = new Scanner(System.in);
String cMessage = scan.nextLine();
ps.println(cMessage);
//Reads and displays response from server
InputStreamReader ir = new InputStreamReader(clientSocket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
System.out.println(message);
}
}
You're never modifying message inside the while loop so you have an infinite loop.
Try
while((message = br.readLine()) != null)
You only loops at the Server side, while u forgot to loop at the Client side, I did a quick fix for you, and also help you closed your connections.
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message;
//= br.readLine();
//Confirms that the message was received
//When this while is here. The match fails and it goes to the else statement.
//Without the while statement it will work and print "Received our hello message."
//when the client says HELLO.
PrintStream ps = new PrintStream(socket.getOutputStream());
while((message =br.readLine())!=null)
{
System.out.println(message);
if(message.equals("HELLO"))
{
ps.println("Received our hello message.");
}
if(message.equals("END"))
{
ps.println("Client ended the connection");
break;
}
else
{
ps.println("Did not receive your hello message");
}
}
ps.close();
br.close();
ir.close();
serverSocket.close();
}
}
Client.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Client myClient = new Client();
myClient.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 9999);
//Sends message to the server
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
Scanner scan = new Scanner(System.in);
String cMessage ="";
InputStreamReader ir = new InputStreamReader(clientSocket.getInputStream());
BufferedReader br = new BufferedReader(ir);
while(!(cMessage.trim().equals("END"))){
cMessage = scan.nextLine();
ps.println(cMessage);
//Reads and displays response from server
String message = br.readLine().trim();
System.out.println(message);
}
br.close();
ir.close();
scan.close();
ps.close();
clientSocket.close();
}
}
Your code is working just fine for sending one 'HELLO' message.
However, like ^Tyler pointed out, If you want to keep sending messages you need to move 'while((message = br.readLine()) != null)' in the while loop.
Using a loop like you are...
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
sleep(in);
if(!in.ready()){
break;
}
}
There is a cheater way that I figured out.
private static void sleep(BufferedReader in) throws IOException {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time < 1000){
if(in.ready()){
break;
}
}
}
This might be sloppy, but if you make a sleep method that waits an amount of time and just keep checking if the BufferedReader is "ready." If it is, you can break out, but then when you come out check again. -- Maybe you could just return a boolean instead of checking twice, but the concept is there.

Categories

Resources