I am working on a web server (done), and thought I would make my own little text-based browser, the only problem is that I can't actually get the browser to read the responses. Here is the code:
import java.io.*;
import java.net.*;
class client
{
static Socket socket = null;
static BufferedReader in = null;
static PrintWriter out = null;
public static void main(String args[])
{
int fromServer;
try
{
socket = new Socket("localhost", 8001);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter( new BufferedOutputStream(socket.getOutputStream()));
out.println("GET /Library/WebServer/Documents/index.html.en HTTP/1.0");
out.flush();
while ((fromServer = in.read()) != -1)
{
System.out.write(fromServer);
System.out.flush();
}
}
catch (UnknownHostException e)
{
System.out.println("Unknown host");
}
catch (IOException e)
{
System.out.println("IO error");
}
}
}
You haven't completely finished the request. You need two newlines, as otherwise it just looks like you're still writing out the request headers.
Add an extra println and you may be okay, although as HTTP specifies CRLF for the line ending, I would actually use print rather than println, and put \r\n at the end of each line explicitly.
(I'd also avoid using PrintWriter, personally - swallowing exceptions is bad...)
Related
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
I am trying to implement a simple java server and client - where client sends "hey" and server sends "hello" back. The problem I am having is even though the server sees hey but client never receives hello.
Here is the server code
try {
InputStream input = clientSocket.getInputStream();
System.out.println("client's request"+ IOUtils.toString(input));
OutputStream output = clientSocket.getOutputStream();
PrintWriter pw = new PrintWriter(output);
pw.write("hello");
pw.flush();
/*BufferedOutputStream bf = new BufferedOutputStream(output);
bf.write("hello".getBytes());*/
/*output.write(("hello").getBytes());*/
long time = System.currentTimeMillis();
System.out.println("Request processed: " + time);
}
catch (IOException e)
{
// report exception somewhere.
e.printStackTrace();
}
Client program
Socket s = new Socket("localhost",9000);
OutputStream out = s.getOutputStream();
out.write("hey".getBytes());
/*PrintWriter pw = new PrintWriter(out);
pw.write("hey");
pw.flush(); */
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while((line =br.readLine())!= null)
{
System.out.println(line);
}
s.close();
I have different variations of reading and writing the input/output but with no luck. Suggestions please.
Thanks
This won't work. IOUtils.toString(input) will read from the input until end of stream, which won't occur until the peer closes the connection, which won't occur at all because he is blocked in readLine() trying to read the response to the request that you are blocked forever reading.
Use BufferedReader.readLine(), but without the loop you have in the client.
This
void writeLine(BufferedWriter writer, String text) throws IOException {
writer.write(text); // the actual characters we want to send
writer.newLine(); // something that signals the end of the message.
writer.flush(); // and we must enforce that these bytes are sent and not buffered locally.
}
can be read by
String readLine(BufferedReader reader) throws IOException {
// reads characters until it finds either a newline or end of stream
// returns data or null when the stream has already ended
return reader.readLine();
}
When you send messages over sockets you must make sure that you have some kind of "protocol" to delimit your messages. For example by sending a newline after each message. That way both sides know where messages in a continuous stream of data ends.
Besides sending the right kind message, you also have to make sure to actually send it. BufferedWriter for example has a data-buffer and will not send data until the buffer is full enough. This will in most cases mean that messages will remain in the buffer instead of being sent over the wire. To do that call flush() once you have written everything you need.
I have different variations of reading and writing the input/output but with no luck.
In your case you don't send a newline but wait for it via readLine. The client should have actually received the "hello" part but it's not going to return from readLine without newline/end of stream (which should happen if you stop the server at this point). The same should apply to the message you send to your server but I guess you do kill the client at this point and therefore see the message.
Here is also the code I made while playing around with this
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;
class Hello {
static int port = 12345;
private static void writeLine(BufferedWriter writer, String line) throws IOException {
System.out.println(">> " + line);
writer.write(line); // the actual characters that we want to send
writer.newLine(); // something that signals the end of the message.
writer.flush(); // and we must enforce that these bytes are sent and not buffered locally.
}
private static String readLine(BufferedReader reader) throws IOException {
// reads characters until it finds either a newline or the end of the stream
// returns data or null when the stream has already ended
return reader.readLine();
}
static void handle(Socket cs, boolean controlling) {
try (Socket socket = cs) {
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
if (controlling) {
writeLine(writer, "hey");
}
loop: while (!Thread.currentThread().isInterrupted()) {
String readLine = readLine(reader);
System.out.println("<< " + readLine);
if (readLine == null)
break;
switch (readLine) {
case "hey":
writeLine(writer, "ho");
break;
case "ho":
writeLine(writer, "bye");
break;
case "bye":
break loop;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
static void server(CountDownLatch latch) {
try (ServerSocket ss = new ServerSocket(port)) {
System.out.println("Listening.");
latch.countDown();
while (!Thread.currentThread().isInterrupted()) {
Socket clientSocket = ss.accept();
// spawn a new thread per client
new Thread(() -> handle(clientSocket, false)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
static void client() {
System.out.println("Connecting.");
try (Socket socket = new Socket("localhost", port)) {
System.out.println("Connected.");
handle(socket, true);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> server(latch)).start();
latch.await();
new Thread(() -> client()).start();
}
}
So i'm trying to make a server/client solution using BufferedReader and BufferedWriter, but it won't work! Using only DataInputStream and DataOutputStream worked perfectly fine, but nothing printed out with the Buffered objects. Where is my error?
public class TServer {
static final int PORT = 8001;
static final int QUEUE = 50;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT, QUEUE)) {
Socket socket = serverSocket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println(input.readLine());
output.write("this is the server!");
output.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
public class TClient {
static final String HOST = "localhost";
static final int PORT = 8001;
public static void main(String[] args) {
try (Socket socket = new Socket(HOST, PORT)) {
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
output.write("this is the client");
output.flush();
System.out.println(input.readLine());
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Using only DataInputStream and DataOutputStream worked perfectly fine, but nothing printed out with the Buffered objects.
The Client is sending the following:
output.write("this is the client");
The Server is trying to read a line with the BufferedReader:
System.out.println(input.readLine());
But no line will be received as the end of line terminator is not sent (hence, the method will block (same goes for the Server, which does not send the end of line terminator)). See the API for BufferedReader, which states:
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.
You are using readLine method of BufferedReader, so you should write newline-terminated string in corresponding BufferedWriter. Like:
output.write("this is the client");
output.newLine();
I am writing a client server based java program. I have two queries I was hoping someone will be able to answer.
First query, Is there a way to check what the client has sent to the server?
Second query is, is there code that will allow the server to check the file they have received from the client? I have been unable to find answers to this online
this is my server code
package servers;
import java.io.*;
import java.net.*;
public class Servers {
public static void main(String [] args)throws Exception
{
try
{
// server variable
ServerSocket server=new ServerSocket(9999);
Socket client=server.accept();
BufferedReader fromClient=new BufferedReader(new InputStreamReader(client.getInputStream()));
String temp=fromClient.readLine();
System.out.println(temp);
System.out.println("Recieved files");
server.close();
while ((temp = fromClient.readLine()) != null)
{
System.out.println(temp);
}
}
catch (Exception ex)
{
}
}
}
this is my client code
package client;
import java.io.*;
import java.net.*;
public class Client{
public static void main(String [] args)throws Exception
{
try
{
File file=new File("C:\\Users\\User\\Desktop\\College 2013\\FYP\\Attribute Data\\Alex.txt");
BufferedReader br=new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
Socket socket=new Socket("Localhost", 9999);
PrintWriter toServer=new PrintWriter(socket.getOutputStream(),true);
BufferedReader fromServer=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String toSend,rec="";
if(!file.exists())
{
System.out.println("File not found terminating program.");
}
br.close();
toServer.println("this is the end");
System.out.println("Finished sending file.");
System.out.println("Begining to receive Server output.");
while (!(rec = fromServer.readLine()).equals("this is the end"))
{
System.out.println(rec);
}
toServer.close();
br.close();
socket.close();
return;
}
catch (Exception e)
{
}
}
}
Any advice would be greatly appreciated
Use a program such as tcpdump or wireshark to watch the network traffic going back and forth. I usually use tcpdump from a command line; however, wireshark has a GUI and maybe some people like that better.
I think it is better to use a separate program to watch the traffic. That way you don't have to complicate your program with extra stuff, and also the external program can be applied to anything that generates network traffic.
You could also setup an intercepting proxy such as OWASP Hatkit Proxy Project
tcptrace works quite well, is very small, for Windows only
http://www.pocketsoap.com/tcptrace/
I am trying to send "Hello" from Server to Client on getting connected... Server side program is running properly but Client side code is having a problem that "Data is not ready to read"
These are my codes... Please Help...
Server Side :
import java.net.*;
import java.io.*;
public class ServerSide
{
public static void main(String args[])
{
try
{
ServerSocket ss = new ServerSocket(8888);
System.out.println("Waiting...");
Socket server=ss.accept();
PrintStream ps= new PrintStream(server.getOutputStream());
ps.print("Hello...");
ps.flush();
System.out.println("Data Sent...");
}
catch(Exception e)
{
System.out.println("Error : " + e.toString());
}
}
}
Client Side :
import java.net.*;
import java.io.*;
public class ClientSide
{
public static void main(String args[])
{
try
{
String str= new String();
Socket client=new Socket(InetAddress.getLocalHost(),8888);
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
if(br.ready())
{
str=br.readLine();
System.out.println(str);
}
else
{
System.out.println("Data not ready to read from Stream");
}
}
catch(Exception e)
{
System.out.println("Error : " + e.toString());
}
}
}
You're currently failing if the BufferedReader hasn't got any data immediately after it's created. Why would you expect it to have? Personally I very rarely find ready() and available() to be useful methods - I suggest you just call readLine and block until there is data available.
As noted in comments, if you're trying to read lines from the client, you need to write lines on the server - so consider using println instead of print. (I'm personally not a fan of PrintStream to start with, but that's a different matter.)
Use
String in = null;
while ((in = br.readLine()) != null) {
// This will loop until EOF and in will hold the last read line
}