cache webpage using java proxy server - java

I'm trying to study client/server using java. Need you help guys. Thanks in advance.
I built a proxy server that connects to the browser, what I would like to do is when it connects to the browser it will cache or download the webpage that the browser visited. Is it possible? Any tips or materials you can suggest? if possible, a sample code would be perfect because I really don't have any idea on how to do it.
Here is my code for my proxy server.
import java.io.*;
import java.net.*;
import java.util.*;
public class test extends Thread {
Socket connectedClient = null;
BufferedReader inFromClient = null; // request from the client (browser)
DataOutputStream outToClient = null; // response to client (browser)
public test(Socket client) {
connectedClient = client;
}
public void run() {
try {
System.out.println( "The Client "+
connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
outToClient = new DataOutputStream(connectedClient.getOutputStream());
String requestString = inFromClient.readLine();
String headerLine = requestString;
StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("The HTTP Client request is ....<BR>");
System.out.println("The HTTP request string is ....");
while (inFromClient.ready())
{
// Read the HTTP complete HTTP Query
responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}
if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
// The default home page
httprequest(200, responseBuffer.toString());
} else {
//filename : request from the client
String fileName = httpQueryString;
fileName = URLDecoder.decode(fileName);
System.out.println("Request:" + fileName);
httprequest(200,fileName);
}
}
else httprequest(404, "<b>The Requested resource not found ....</b>");
} catch (Exception e) {
e.printStackTrace();
}
}
public void httprequest(int statusCode,String location) throws Exception {
HttpURLConnection connection = null;
StringBuilder sb = null;
String line = null;
URL serverAddress = null;
String statusLine = null;
String serverdetails = "Server: Java ProxyServer";
String contentTypeLine = "Content-type: text/html\n\n";
if (statusCode == 200)
{
statusLine = "HTTP/1.1 200 OK" + "\r\n";
try {
serverAddress = new URL(location);
connection = null;
connection = (HttpURLConnection)serverAddress.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
//read the result from the server
InputStream rd = connection.getInputStream();
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes("\r\n");
byte[] buffer = new byte[1024] ;
int bytesRead;
while ((bytesRead = rd.read(buffer)) != -1 ){
outToClient.write(buffer, 0, bytesRead);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
}
}
else{
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
}
outToClient.close();
}
public static void main (String args[]) throws Exception {
//System.setProperty("http.proxyHost","172.16.1.254") ;
// System.setProperty("http.proxyPort", "3128") ;
ServerSocket Server = new ServerSocket (8080, 0, InetAddress.getByName("localhost"));
System.out.println ("Proxy Server Waiting for client on port 8080");
while(true) {
Socket connected = Server.accept();
(new test(connected)).start();
}
}
}

I hope you want monitor HTTP trafic, Take a reference from this, http://www.java2s.com/Code/Java/Network-Protocol/Asimpleproxyserver.htm even I built by my own by taking references from this kinda resources. But SSL communication you cannot do monitoring.

Related

Connect to localhost with java but nothing happened but it works with nodejs client file

I am trying to connect to localhost with a java app, and I have a server side code with nodeJS and.It's my first time to deal with nodeJS, when I created a server.js and client.js every thing was working correctly and I could send and receive messages to and from the server but when I tried to use java code(Socket) nothing happened but there is no errors. I can't find the reason and it's my first time I use nodeJS so I feel stuck, can any one give me advises or find out where is my mistake.
Here is my java code
String hostName = "localhost";
int portNumber = 8081;
try {
System.out.println("Connecting to " + hostName + " on port " + portNumber);
Socket client = new Socket(hostName, portNumber);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
out.writeInt(5);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e) {
e.printStackTrace();
}
And here is my server code with nodeJS
var http = require('http');
var fs = require('fs');
var url = require('url');
// Create a server
http.createServer( function (request, response) {
var b = new Buffer("Return something");
response.write(b.toString());
console.log('listening to client');
response.end();
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
And here is my client code with nodeJS, it works fine
var http = require('http');
// Options to be used by request
var options = {
host: 'localhost',
port: '8081',
path: '/index.htm'
};
// Callback function is used to deal with response
var callback = function(response){
// Continuously update stream with data
var body = '';
response.on('data', function(data) {
body += data;
});
response.on('end', function() {
// Data received completely.
console.log(body);
});
}
// Make a request to the server
var req = http.request(options, callback);
req.end();
Try this ...
String hostName = "127.0.0.1";
int portNumber = 8081;
try {
System.out.println("Connecting to " + hostName + " on port " + portNumber);
Socket client = new Socket(hostName, portNumber);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
//OutputStream outToServer = client.getOutputStream();
//DataOutputStream out = new DataOutputStream(outToServer);
PrintWriter pw = new PrintWriter(client.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: 127.0.0.1");
pw.println()
pw.println("<html><body><h1>Hello world<\\h1><\\body><\\html>")
pw.println()
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String t;
while((t = br.readLine()) != null) System.out.println(t);
br.close();
}catch(IOException e) {
e.printStackTrace();
}
To access an HTTP resource in Java, you don't need to use the socket API, which is too low-level. You are not using it in the NodeJS client code.
import java.io.IOException;
import java.net.URL;
import java.util.Scanner;
public class Http {
public static String get(String url) throws IOException {
try (Scanner scanner = new Scanner(new URL(url).openStream())) {
return scanner.useDelimiter("\\A").next();
}
}
}
Then you can use it like this:
try {
String content = Http.get("http://localhost:8080/index.htm");
} catch (IOException e) {
e.printStackTrace();
}

Socket client: don't get the full response with DataInputStream.readUTF()

I want to write a socket client to send a request to a server and get response back. It works, but not right.
Here is my code:
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.error(e);
this.log.error("Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.error("Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if (StringUtils.isBlank(response)) return null;
return response;
}
The problem is: I didn't got the full response with in.readUTF(). I always got a response with the same length as the sent data's length (variable data). I have tested with other GUI client and got the full response. So it's not a problem of the server.
Does someone known, what i did wrong?
UPDATE
Thanks EJP and Andrey Lebedenko. I think, my problems are the functions writeUTF and readUTF. So i have edited my code in the try block so:
Charset charset = Charset.forName("ISO-8859-1");
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.write(data.getBytes(charset));
final InputStream inFromServer = client.getInputStream();
final BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, charset));
response = in.readLine();
And it worked now.
If it works with Telnet, as per your comment, the server isn't using readUTF(), so your writeUTF() is already wrong, and the server is therefore unlikely to be using writeUTF() either, which would make your readUTF() wrong as well. You can't use these methods arbitrarily: they can only interchange data between themselves.
I'll bet your GUI client that works doesn't use them either.
Without knowing what does server part do, it is kind of difficult (if possible at all) to trace down the root cause. So in the most honest hope that it will help I just share this code with which I've tested the fragment above.
package tcpsendreceive;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SendReceive {
private static final Logger log = Logger.getLogger(SendReceive.class.toString());
private final String host;
private final int port;
private Server server;
class Server extends Thread
{
private final ServerSocket serverSocket;
public Server(ServerSocket s)
{
serverSocket = s;
}
#Override
public void run()
{
Socket connection;
SendReceive.this.log.log(Level.INFO, "Server: DoubleEcho Server running on "+this.serverSocket.getLocalPort());
try{
do {
connection = this.serverSocket.accept();
SendReceive.this.log.log(Level.INFO, "Server: new connection from "+connection.getRemoteSocketAddress());
int b;
do {
DataInputStream in = new DataInputStream(connection.getInputStream());
String s = in.readUTF();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeUTF(s+","+s); // echo it back TWICE
out.flush();
connection.shutdownOutput();
connection.close();
} while(!connection.isClosed());
}
while(true);
}
catch(IOException ioe)
{
SendReceive.this.log.log(Level.SEVERE, "IOException in server! - STOP", ioe);
}
finally {
try{
this.serverSocket.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
try{
if(!connection.isClosed())
connection.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
}
}
}
public SendReceive(String host, int port)
{
this.host = host;
this.port = port;
try{
this.server = new Server(new ServerSocket(this.port));
this.server.start();
}
catch(IOException ioe)
{
this.log.log(Level.SEVERE, "IOException while creating server! - STOP", ioe);
}
}
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if(response == null || response.isEmpty())
return null;
return response;
}
}
Test-demo
package tcpsendreceive;
public class Main {
public static void main(String[] args)
{
String data = "AAABBB";
SendReceive sr = new SendReceive("localhost", 5000);
String res = sr.send(data);
System.out.println("Sent: "+data);
System.out.println("Received: "+res);
}
}
Result (key part):
Sent: AAABBB
Received: AAABBB,AAABBB
Hope it helps.
EDIT
1. Corrected wrapper flush instead of socket stream flush. Still believe it is good practice to flush the stream wrapper before closing the socket.
Client socket closed in IOException block (since they aren't automatically closed on ServerSocket shutdown). Thanks #EJP
P.s. I should admit I was bit surprised by such an attention to the humble test server code, especially compared to other dirty tests we all have seen on SO. Flattered. :)

map file directory from a java server to local machine

I have created a java server application which will take GET requests and return files to the browser. Also the files are downloaded to the directory using "content-disposition:attachment" in header.But this only downloads as files, I want to download as a folder and map it to a local directory. for example
localhost:8080/xyz.jpg gives u an image .But localhost:8080/src/xyz.jpg should be downlaoded as src folder with an image in it eg: downloads/src/xyz.jpg. Currently if i do that ,it downloads as just a file. Since you guys asked.Here is the example code i used :) .thanks
import java.io.*;
import java.net.*;
import java.util.*;
public class myHTTPServer extends Thread {
static final String HTML_START =
"<html>" +
"<title>HTTP Server in java</title>" +
"<body>";
static final String HTML_END =
"</body>" +
"</html>";
Socket connectedClient = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;
public myHTTPServer(Socket client) {
connectedClient = client;
}
public void run() {
try {
System.out.println( "The Client "+
connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
outToClient = new DataOutputStream(connectedClient.getOutputStream());
String requestString = inFromClient.readLine();
String headerLine = requestString;
StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("<b> This is the HTTP Server Home Page.... </b><BR>");
responseBuffer.append("The HTTP Client request is ....<BR>");
System.out.println("The HTTP request string is ....");
while (inFromClient.ready())
{
// Read the HTTP complete HTTP Query
responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}
if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
// The default home page
sendResponse(200, responseBuffer.toString(), false);
} else {
//This is interpreted as a file name
String fileName = httpQueryString.replaceFirst("/", "");
fileName = URLDecoder.decode(fileName);
if (new File(fileName).isFile()){
sendResponse(200, fileName, true);
}
else {
sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
}
}
}
else sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {
String statusLine = null;
String serverdetails = "Server: Java HTTPServer";
String contentLengthLine = null;
String fileName = null;
String contentTypeLine = "Content-Type: text/html" + "\r\n";
String Content_disposition="Content-Disposition: attachment; filename='src/fname.ext'";
FileInputStream fin = null;
if (statusCode == 200)
statusLine = "HTTP/1.1 200 OK" + "\r\n";
else
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
if (isFile) {
fileName = responseString;
fin = new FileInputStream(fileName);
contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
contentTypeLine = "Content-Type: \r\n";
}
else {
responseString = myHTTPServer.HTML_START + responseString + myHTTPServer.HTML_END;
contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
}
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes(contentLengthLine);
outToClient.writeBytes(Content_disposition);
outToClient.writeBytes("Connection: close\r\n");
outToClient.writeBytes("\r\n");
if (isFile) sendFile(fin, outToClient);
else outToClient.writeBytes(responseString);
outToClient.close();
}
public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
byte[] buffer = new byte[1024] ;
int bytesRead;
while ((bytesRead = fin.read(buffer)) != -1 ) {
out.write(buffer, 0, bytesRead);
}
fin.close();
}
public static void main (String args[]) throws Exception {
ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
System.out.println ("TCPServer Waiting for client on port 5000");
while(true) {
Socket connected = Server.accept();
(new myHTTPServer(connected)).start();
}
}
}
You can't do this using the HTTP protocol and a normal browser, there is no MIME type for folders. Your browser is able to download only files.
If you want to do this through HTTP:
Option 1: Generate a "zip" file (or some other format that enables you to package a folder tree into a single file) which contains the folder tree and send that to the browser.
Option 2: Develop a custom client program that is able to interpret the response that it gets from the server and create the corresponding folders on the local filesystem.

Java Server: Socket sending HTML code to browser

I am trying to write a simple Java program using ServerSockets that will send some HTML code to the browser. Here is my code:
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(55555);
} catch (IOException e) {
System.err.println("Could not listen on port: 55555.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
if(clientSocket != null) {
System.out.println("Connected");
}
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html");
out.println("\r\n");
out.println("<p> Hello world </p>");
out.flush();
out.close();
clientSocket.close();
serverSocket.close();
I then go to localhost:55555 in my browser and nothing displays. I know the connection is working because the program outputs "Connected" as checked in the if statement. I have also tried outputting the data from the inputStream and that works. But the text I am trying to output in the browser is not displaying at all, the program finishes running and I get a
"Problem loading page - the connection has been reset"
in my browser, but no text.
I have searched the internet and it seems everyone else coding it this way is having their text display fine, they are having other problems.
How can I fix this?
I tested your code in Chrome, Firefox, IE, and Opera and it works.
However, I would suggest that you use multi-threading and essentially spawn a new thread to handle each new request.
You can create a class that implements runnable and takes a clientSocket within the constructor. This will essentially make your custom webserver capable of accepting more than one request concurrently.
You will also need a while loop if you want to handle more than one total requests.
A good read demonstrating the above: https://web.archive.org/web/20130525092305/http://www.prasannatech.net/2008/10/simple-http-server-java.html
If the web-archive is not working, I'm posting the code below (taken from above):
/*
* myHTTPServer.java
* Author: S.Prasanna
* #version 1.00
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class myHTTPServer extends Thread {
static final String HTML_START =
"<html>" +
"<title>HTTP Server in java</title>" +
"<body>";
static final String HTML_END =
"</body>" +
"</html>";
Socket connectedClient = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;
public myHTTPServer(Socket client) {
connectedClient = client;
}
public void run() {
try {
System.out.println( "The Client "+
connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
outToClient = new DataOutputStream(connectedClient.getOutputStream());
String requestString = inFromClient.readLine();
String headerLine = requestString;
StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("<b> This is the HTTP Server Home Page.... </b><BR>");
responseBuffer.append("The HTTP Client request is ....<BR>");
System.out.println("The HTTP request string is ....");
while (inFromClient.ready())
{
// Read the HTTP complete HTTP Query
responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}
if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
// The default home page
sendResponse(200, responseBuffer.toString(), false);
} else {
//This is interpreted as a file name
String fileName = httpQueryString.replaceFirst("/", "");
fileName = URLDecoder.decode(fileName);
if (new File(fileName).isFile()){
sendResponse(200, fileName, true);
}
else {
sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
}
}
}
else sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {
String statusLine = null;
String serverdetails = "Server: Java HTTPServer";
String contentLengthLine = null;
String fileName = null;
String contentTypeLine = "Content-Type: text/html" + "\r\n";
FileInputStream fin = null;
if (statusCode == 200)
statusLine = "HTTP/1.1 200 OK" + "\r\n";
else
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
if (isFile) {
fileName = responseString;
fin = new FileInputStream(fileName);
contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
contentTypeLine = "Content-Type: \r\n";
}
else {
responseString = myHTTPServer.HTML_START + responseString + myHTTPServer.HTML_END;
contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
}
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes(contentLengthLine);
outToClient.writeBytes("Connection: close\r\n");
outToClient.writeBytes("\r\n");
if (isFile) sendFile(fin, outToClient);
else outToClient.writeBytes(responseString);
outToClient.close();
}
public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
byte[] buffer = new byte[1024] ;
int bytesRead;
while ((bytesRead = fin.read(buffer)) != -1 ) {
out.write(buffer, 0, bytesRead);
}
fin.close();
}
public static void main (String args[]) throws Exception {
ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
System.out.println ("TCPServer Waiting for client on port 5000");
while(true) {
Socket connected = Server.accept();
(new myHTTPServer(connected)).start();
}
}
}
Enjoy!
You need to need to set the PrintWriter to autoflush when it prints.
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
should be
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
The line terminator in HTTP is \r\n. This means that you shouldn't use println(), you should use print() and add an explicit \r\n yourself to each line.
The result of an HTTP GET is supposed to be an HTML document, not a fragment. Browsers are entitled to ignore or complain. Send this:
<html>
<head/>
<body>
<p> Hello world </p>
</body>
</html>
in my computer, at least to get the socket's inputStream:
clientSocket.getInputStream();
with out this line, sometimes chrome doesn't work
you need read the input from socket first
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = "";
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
if(line.isEmpty())
break;
}
You should accept the request sent by client(browser in this case),to do that just add the following lines:
Buffered reader in = new Buffered reader(new InputStreamReader(client_socket.getInputStream()));
Note: you need to replace the "client_socket" part with name of your own socket for the client.
Why we need to accept browser request?
It's because if we don't accept the request browser doesn't get any acknowledgement from the server that the request that was sent is received,hence it thinks the server is not reachable any more.
My code:
public class Help {
public static void main(String args) throws IOException{
ServerSocket servsock new serverSocket(80)
Socket cs servsock, accept();
Printwriter out new Printwriter(Cs.getoutputstream), true)
BufferedReader in new BufferedReader(new InputStreamReader(cs.getInputStream());
out.println("<html> <body> <p>My first StackOverflow answer </p> </body> </html>");
out.close();
servsock.close();
}
}
You need to send
"HTTP/1.1 200 OK" first. followed by a newline
then "Content-Type: text/html; charset: UTF-8" followed by 2 newlines.
then send the HTML source for it to display as a styled webpage and not just a text output.
I used OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");
osw.write("<html><head><title>Hello World</title></head><body></body><p>Hello World</p></body></html>");
Not sending "HTTP/1.1 200 OK" first results in source code being displayed without html parsing..
And to avoid "Connection being reset" error, you need to close your socket. Very Important !!
The whole code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer
{
ServerSocket serverSocket;
Socket socket;
FileReader fr;
OutputStreamWriter osw;
WebServer() throws IOException
{
serverSocket = new ServerSocket(8080);
socket = serverSocket.accept();
fr = new FileReader("index.html");
osw = new OutputStreamWriter(socket.getOutputStream());
osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");
int c;
char[] ch = new char[4096];
while ((c = fr.read(ch)) != -1)
{
osw.write(ch, 0, c);
}
osw.close();
socket.close();
}
public static void main(String[] args) throws IOException
{
new WebServer();
}
}

Java server-client readLine() method

I have a client class and a server class.
If client sends message to server, server will send response back to the client, then client will print all the messages it received.
For example,
If Client sends "A" to Server, then Server will send response to client
"1111". So I use readLine() in client class to read the message from server, then client print "1111" in the console.
If Client sends "B" to Server, then Server will send response to client
"2222\n 3333". So the expected printing output from client is:
"2222"
"3333"
So the response message from server to client may have 1 line or 2 lines depending on the message it send from client to server.
My question is that how I can use readLine() to read the message that send from server to client. More specifically, if I use the following codes,
String messageFromServer;
while(( messageFromServer = inputStreamFromServer.readLine()) != null) {
println(messageFromServer);
}
It will only print the first line, and will not print anything else even if I keep sending message from client to server, because readLine() will stops once it has read the first line.
update:
More specifically, I am looking for some methods in the client class to read message that contains 1 or multiple lines from server at a time. I am wondering if there are any ways to do it in client side if I don't want to change the format of the message that sent from server to client.
update 2
To make my question more clear, I will put some sample codes in the following:
This is server:
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(1234);
} catch (IOException e) {
System.err.println("Could not listen on port: 1234.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
}
System.out.println("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient =null;
String textToClient =null;
textFromClient = in.readLine(); // read the text from client
if( textFromClient.equals("A")){
textToClient = "1111";
}else if ( textFromClient.equals("B")){
textToClient = "2222\r\n3333";
}
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
The client:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try {
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection");
}
System.out.println("Connected");
String textToServer;
while((textToServer = read.readLine())!=null){
out.print(textToServer + "\r\n" ); // send to server
out.flush();
String messageFromServer =null;
while(( messageFromServer = textToServer=in.readLine()) != null){
System.out.println(messageFromServer);
}
}
out.close();
in.close();
read.close();
socket.close();
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
You shouldn't need to change the format of the data sent by the server, and readLine() should work, but I suspect that the server is not flushing or closing the OutputStream after writing the response which could possibly explain things.
Is the call to readLine() hanging? Are you in control of the server code? If so, can you include it?
Revised classes that work as I believe you expect:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ClientServerTest2
{
public static void main(String[] args) throws Exception
{
Thread serverThread = new Thread(new Server());
serverThread.start();
Thread clientThread = new Thread(new Client());
clientThread.start();
serverThread.join();
clientThread.join();
}
private static class Server implements Runnable
{
#Override
public void run()
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(1234);
Socket clientSocket = null;
clientSocket = serverSocket.accept();
debug("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient = null;
String textToClient = null;
textFromClient = in.readLine(); // read the text from client
debug("Read '" + textFromClient + "'");
if ("A".equals(textFromClient))
{
textToClient = "1111";
}
else if ("B".equals(textFromClient))
{
textToClient = "2222\r\n3333";
}
debug("Writing '" + textToClient + "'");
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void debug(String msg)
{
System.out.println("Server: " + msg);
}
}
private static class Client implements Runnable
{
#Override
public void run()
{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try
{
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
debug("Connected");
String textToServer;
textToServer = read.readLine();
debug("Sending '" + textToServer + "'");
out.print(textToServer + "\r\n"); // send to server
out.flush();
String serverResponse = null;
while ((serverResponse = in.readLine()) != null)
debug(serverResponse); // read from server and print it.
out.close();
in.close();
read.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
Change while(( messageFromServer = inputStreamFromServer.readLine() != null) to while(( messageFromServer = inputStreamFromServer.readLine()) != null)
Actually this shouldn't even compile....
It's a work around.
If you want to send multiple strings like in your case : "2222\n 3333".
You can send them by adding a seperator character (like :) between two strings : "2222: 3333".
Then you can call write from server side as
clientOut.write("2222: 3333\n");
On client side parse recieved String :
messageFromServer = inputStreamFromServer.readLine();
String strArray[] = messageFromServer.split(":");
strArray[0] : 2222
strArray[0] : 3333

Categories