JAVA pdf response error in implementing http 1 socket programming - java

I run my java webserver on port 6799
My directory has a txt.txt file and pdf.pdf file
When I give localhost:6799/txt.txt, it gives perfect output saying
GET /txt.txt HTTP/1.1HTTP/1.0 200 OK
Content-type: text/plain
This is a very simple text file
But when I give localhost:6799/pdf.pdf from browser, it gives java.lang.NullPointerException
This is my code
import java.net.*;
public final class WebServer {
public static void main(String args[]) throws Exception {
int port = 6799;
System.out.println("\nListening on port " + port);
ServerSocket listen = new ServerSocket(port);
while (true) {
Socket socket = listen.accept();
HttpRequest request = new HttpRequest(socket);
Thread thread = new Thread(request);
thread.start();
}
}
}
--
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;
public final class HttpRequest implements Runnable {
final String CRLF = "\r\n";
Socket socket;
public HttpRequest(Socket socket) throws Exception {
this.socket = socket;
}
#Override
public void run() {
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
}
private void processRequest() throws Exception {
BufferedReader br;
DataOutputStream dos;
try (InputStream is = socket.getInputStream()) {
br = new BufferedReader(new InputStreamReader(is));
String requestline = br.readLine();
System.out.println("\n" + requestline);
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
dos = new DataOutputStream(socket.getOutputStream());
dos.writeBytes(requestline);
StringTokenizer tokens = new StringTokenizer(requestline);
tokens.nextToken(); // skip over the method, which should be "GET"
String fileName = tokens.nextToken();
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "HTTP/1.0 200 OK" + CRLF;
contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
} else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
//contentTypeLine = "Content-type: " + "text/html" + CRLF;
entityBody = "<HTML>"
+ "<HEAD><TITLE>Not Found</TITLE></HEAD>"
+ "<BODY>Not Found</BODY></HTML>";
}
dos.writeBytes(statusLine);
dos.writeBytes(contentTypeLine);
dos.writeBytes(CRLF);
if (fileExists) {
sendBytes(fis, dos);
fis.close();
} else {
dos.writeBytes(entityBody);
}
}
br.close();
dos.close();
socket.close();
}
private void sendBytes(FileInputStream fis, DataOutputStream dos) throws IOException {
byte[] buffer = new byte[4096];
int bytes = 0;
while ((bytes = fis.read(buffer)) != -1) {
dos.write(buffer, 0, bytes);
}
}
private String contentType(String fileName) {
if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
if (fileName.endsWith(".txt")) {
return "text/plain";
}
if (fileName.endsWith(".pdf")) {
return "application/pdf";
}
return "application/octet-stream";
}
}
STACK TRACE
java.lang.NullPointerException
at java.io.DataOutputStream.writeBytes(DataOutputStream.java:274)
at HttpRequest.processRequest(HttpRequest.java:65)
at HttpRequest.run(HttpRequest.java:20)
at java.lang.Thread.run(Thread.java:724)

At least one issue is this code:
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
BufferedReader will return null at the end of the stream, so calling .length() on a null object will yield a NullPointerException.
A more idiomatic way to write this is:
while ((headerLine = br.readLine()) != null && headerLine.length() != 0) {
System.out.println(headerLine);
}
...which takes advantage of short-circuit logic to not evaluate the second condition if the result of (headerLine = br.readLine()) is null.

It is happening because for some reason you have toggled comment on the following line:
//contentTypeLine = "Content-type: " + "text/html" + CRLF;
Untoggle it and you're good!

Related

Browser wont identify HTTP response header?

import java.io.*;
import java.net.*;
public class WebServer{
private void run(){
try {
ServerSocket serverSocket = new ServerSocket(5520);
while(true){
try {
Socket serverClient = serverSocket.accept();
WebServerThread wst = new WebServerThread(serverClient);
wst.start();
} catch (IOException evt) {
System.out.println("Error");
}
}
} catch (IOException evt) {
System.out.println("error");
}
}
public static void main(String[] args) {
WebServer ws = new WebServer();
System.out.println("Server is up and running.");
ws.run();
}
}
import java.io.*;
import java.net.*;
import java.lang.*;
class WebServerThread extends Thread {
Socket serverClient;
BufferedReader in = null;
public WebServerThread(Socket clientSocket) {
serverClient = clientSocket;
}
public void run() {
try {
in = new BufferedReader(new InputStreamReader(serverClient.getInputStream()));
//System.out.println(in.readLine());
HTTP http = new HTTP(in.readLine(), serverClient);
in.close();
serverClient.close();
} catch (IOException e) {
System.out.println("Error");
} catch (NullPointerException e){
System.out.println("bad");
}
}
}
import java.io.*;
import java.nio.Buffer;
import java.util.StringTokenizer;
import java.net.*;
public class HTTP {
String contentTypeLine;
String file;
String version = "HTTP/1.1";
//String crlf = "\\r\\n";
String statusLine;
String responseHeader;
String statusCodePhrase;
String headerFieldName = "Content-type: ";
String headerValue;
String header;
public HTTP(String request, Socket socket) throws IOException {
StringTokenizer st = new StringTokenizer(request);
st.nextToken();
file = "." + st.nextToken();
try {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
headerValue = contentType(file);
statusLine = "HTML/1.0 200 OK\r\n";
responseHeader = "Content-type: " + headerValue + "\r\n";
dos.writeBytes(statusLine);
dos.writeBytes(responseHeader);
dos.writeBytes("\r\n");
System.out.println(statusLine);
System.out.println(responseHeader);
System.out.println("Client requesting file: " + file);
writeEntityBody(file, bin, dos);
System.out.println("FIle: " + file + " sent successfully.");
} catch (FileNotFoundException evt) {
System.out.println(file + " not found.");
System.out.println("Requested file does not exist.");
statusCodePhrase = "404 Not Found";
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeBytes("<HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>"
+ "<BODY>Not Found</BODY></HTML>");
} catch (IOException evt) {
System.out.println("Bad");
}
}
private void writeEntityBody(String file, BufferedInputStream bin, DataOutputStream dos) throws IOException {
int CHUNK_SIZE = 1024;
byte[] buffer = new byte[CHUNK_SIZE];
int len;
while ((len = bin.read(buffer)) != -1) {
dos.write(buffer, 0, len);
}
bin.close();
dos.flush();
dos.close();
}
private String contentType(String file){
String extension = file.split("\\.")[2];
if(extension.equals("htm") || extension.equals("html") || extension.equals("txt")){
contentTypeLine = "text/html";
}
else if(extension.equals("jpg") || extension.equals("gif") || extension.equals("png") || extension.equals("bmp") || extension.equals("pdf")) {
contentTypeLine = "image/bmp";
}
else{
return "application/octet-stream";
}
return contentTypeLine;
}
}
So basically, my server listens for a request from the client, which is the browser, so if I type "127.0.0.1:5520/test.txt" it connects to port 5520 and requests the file "test.txt".
In terms of listening for requests and starting threads, its fine. But in the HTTP class, when my program performs these lines:
headerValue = contentType(file);
statusLine = "HTML/1.0 200 OK\r\n";
responseHeader = "Content-type: " + headerValue + "\r\n";
dos.writeBytes(statusLine);
dos.writeBytes(responseHeader);
dos.writeBytes("\r\n");
That ideally should create the header and the browser should identify that. But the browser is just writing all of that as if it were part of the message body.
I've tried it on several different browsers and these were the results:
IE: Displays statusLine, responseHeader as if it were part of the message body and displays the contents of the file.
Firefox: Throws out statusLine, displays responseHeader as part of the message body and displays the content of the file.
Chrome: ERR_INVALID_HTTP_RESPONSE
I'm not sure why the browser can't identify the header.
Hint: the protocol is called "HTTP", not "HTML".

FileoutputStream doesn't output any string after the empty line (Line break) [duplicate]

This question already has answers here:
Why fileOutputStream can't output any string after an empty line (or a line break) in client-server application?
(2 answers)
Closed 7 years ago.
In my client-server application, when I try to download a file from the serverSide, the file gets downloaded; but the header information such as some additional text with line break can't be read. As you can see in my Server class this following information is supposed to be printed out in the client side.
outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
fileSize, filename);
But it doesn't. Only the fisrt string (Status OK) before the \r\n gets printed, not any string after \r\n.
How can I fix it?
My complete code:
ServerSide:
public class ServerSide {
private BufferedReader inputFromClient;
private PrintWriter outputToClient;
private FileInputStream fis;
private OutputStream os;
private static final int PORT = 8000;
private ServerSocket serverSocket;
private Socket socket;
public static void main(String[] args) {
int port = PORT;
if (args.length == 1) {
port = Integer.parseInt(args[0]);
}
new ServerSide(port);
}
private boolean fileExists(File[] files, String filename) {
boolean exists = false;
for (File file : files) {
if (filename.equals(file.getName())) {
exists = true;
}
}
return exists;
}
public ServerSide(int port) {
// create a server socket
try {
serverSocket = new ServerSocket(port);
} catch (IOException ex) {
System.out.println("Error in server socket creation.");
System.exit(1);
}
while (true) {
try {
socket = serverSocket.accept();
outputToClient = new PrintWriter(socket.getOutputStream());
inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String request = inputFromClient.readLine();
if (!request.startsWith("exit") && !request.startsWith("pwd") && !request.startsWith("list") && !request.startsWith("GET")) {
outputToClient.println("Wrong request\r\n"
+ "\r\n");
} else if (request.startsWith("exit")) {
break;
} else if (request.startsWith("pwd")) {
File file = new File(System.getProperty("user.dir"));
outputToClient.print("Status OK\r\n"
+ "Lines 1\r\n"
+ "\r\n"
+ "Working dir: " + file.getName() + "\r\n");
} else if (request.startsWith("list")) {
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
outputToClient.print("Status OK\r\n"
+ "Files " + files.length + "\r\n"
+ "\r\n"
+ Arrays.toString(files).substring(1, Arrays.toString(files).length() - 1) + "\r\n");
} else if (request.startsWith("GET")) {
String filename = request.substring(4);
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
if (fileExists(files, filename)) {
file = new File(filename);
int fileSize = (int) file.length();
outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
fileSize, filename);
outputToClient.flush();
try (FileInputStream fis = new FileInputStream(file)) {
os = socket.getOutputStream();
byte[] buffer = new byte[(1 << 7) - 1];
int bytesRead = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
}
//os.close();
// fis.close();
} else {
outputToClient.print("Status 400\r\n"
+ "File " + filename + " not found\r\n"
+ "\r\n");
outputToClient.flush();
}
}
outputToClient.flush();
}
} catch (IOException e) {
System.err.println(e);
}
}
}
}
ClientSide:
public class ClientSide {
private static Socket socket;
private static PrintWriter outputToServer;
private static BufferedReader inputFromServer;
private static InputStream is;
private static FileOutputStream fos;
private static final int PORT = 8000;
private static final String SERVER = "85.197.159.45";
boolean Connected;
DataInputStream serverInput;
public static void main(String[] args) throws InterruptedException {
String server = "localhost";
int port = PORT;
if (args.length >= 1) {
server = args[0];
}
if (args.length >= 2) {
port = Integer.parseInt(args[1]);
}
new ClientSide(server, port);
}
public ClientSide(String server, int port) {
try {
socket = new Socket(server, port);
serverInput = new DataInputStream(socket.getInputStream());
outputToServer = new PrintWriter(socket.getOutputStream(), true);
inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Client is connected! ");
Connected = true;
String line = null;
Scanner sc = new Scanner(System.in);
System.out.print("Type command: ");
while (sc.hasNextLine()) {
String request = sc.nextLine();
if (request.startsWith("exit")) {
outputToServer.println(request);
System.out.println("Application exited!");
//outputToServer.flush();
break;
} else if (request.startsWith("pwd")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("list")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("GET")) {
System.out.print("\r\n");
outputToServer.println(request);
outputToServer.flush();
}
while (Connected) {
line = inputFromServer.readLine();
System.out.println(line);
if (line.isEmpty()) {
Connected = false;
if (inputFromServer.ready()) {
System.out.println(inputFromServer.readLine());
}
}
if (line.startsWith("Status 400")) {
while (!(line = inputFromServer.readLine()).isEmpty()) {
System.out.println(line);
}
break;
}
if (request.startsWith("GET")) {
File file = new File(request.substring(4));
is = socket.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[socket.getReceiveBufferSize()];
serverInput = new DataInputStream(socket.getInputStream());
//int bytesReceived = 0;
byte[] inputByte = new byte[4000];
int length;
while ((length = serverInput.read(inputByte, 0, inputByte.length)) > 0) {
fos.write(inputByte, 0, length);
}
request = "";
fos.close();
}
}
System.out.print("\nType command: ");
Connected = true;
}
outputToServer.close();
inputFromServer.close();
socket.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
You should close the output stream outputToClient.close() after final outputToClient.flush()

Why server-side shows a null pointer exception (in client server application)?

In my client server application, client sends some commands and the server gives the results back. Now the problem is when the client tries to download a file from the server, by using GET filename command. The program works fine, even it can doesnload the file correctly, but the problem is in the server side's command prompt there is always a null pointer exception error remains. And it happens immediately after I enter the GET command. Error:
Second issue appears when I remove fis.close(); line in serverside. It shows another trace error in the server side: Error:
This is the complete project I am working on:
ClientSide:
package clientside;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class ClientSide {
private static Socket socket;
private static PrintWriter outputToServer;
private static BufferedReader inputFromServer;
private static InputStream is;
private static FileOutputStream fos;
private static final int PORT = 8000;
private static final String SERVER = "85.197.159.45";
boolean Connected;
DataInputStream serverInput;
public static void main(String[] args) throws InterruptedException {
String server = "localhost";
int port = PORT;
if (args.length >= 1) {
server = args[0];
}
if (args.length >= 2) {
port = Integer.parseInt(args[1]);
}
new ClientSide(server, port);
}
public ClientSide(String server, int port) {
try {
socket = new Socket(server, port);
serverInput = new DataInputStream(socket.getInputStream());
outputToServer = new PrintWriter(socket.getOutputStream(), true);
inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Client is connected! ");
Connected = true;
String line = null;
Scanner sc = new Scanner(System.in);
System.out.print("Type command: ");
while (sc.hasNextLine()) {
String request = sc.nextLine();
if (request.startsWith("exit")) {
outputToServer.println(request);
System.out.println("Application exited!");
//outputToServer.flush();
break;
} else if (request.startsWith("pwd")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("list")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("GET")) {
System.out.print("\r\n");
outputToServer.println(request);
outputToServer.flush();
}
while (Connected) {
line = inputFromServer.readLine();
System.out.println(line);
if (line.isEmpty()) {
Connected = false;
if (inputFromServer.ready()) {
System.out.println(inputFromServer.readLine());
}
}
if (line.startsWith("Status 400")) {
while (!(line = inputFromServer.readLine()).isEmpty()) {
System.out.println(line);
}
break;
}
if (request.startsWith("GET")) {
File file = new File(request.substring(4));
is = socket.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[socket.getReceiveBufferSize()];
serverInput = new DataInputStream(socket.getInputStream());
//int bytesReceived = 0;
byte[] inputByte = new byte[4000];
int length;
while ((length = serverInput.read(inputByte, 0, inputByte.length)) > 0) {
fos.write(inputByte, 0, length);
}
/*
while ((bytesReceived = is.read(buffer)) >=0) {
//while ((bytesReceived = is.read(buffer))>=buffer) {
fos.write(buffer, 0, bytesReceived);
}
*/
request = "";
fos.close();
is.close();
}
}
System.out.print("\nType command: ");
Connected = true;
}
outputToServer.close();
inputFromServer.close();
socket.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
ServerSide:
package serverside;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class ServerSide {
private BufferedReader inputFromClient;
private PrintWriter outputToClient;
private FileInputStream fis;
private OutputStream os;
private static final int PORT = 8000;
private ServerSocket serverSocket;
private Socket socket;
public static void main(String[] args) {
int port = PORT;
if (args.length == 1) {
port = Integer.parseInt(args[0]);
}
new ServerSide(port);
}
private boolean fileExists(File[] files, String filename) {
boolean exists = false;
for (File file : files) {
if (filename.equals(file.getName())) {
exists = true;
}
}
return exists;
}
public ServerSide(int port) {
// create a server socket
try {
serverSocket = new ServerSocket(port);
} catch (IOException ex) {
System.out.println("Error in server socket creation.");
System.exit(1);
}
while (true) {
try {
socket = serverSocket.accept();
os = socket.getOutputStream();
outputToClient = new PrintWriter(socket.getOutputStream());
inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String request = inputFromClient.readLine();
if (!request.startsWith("exit") && !request.startsWith("pwd") && !request.startsWith("list") && !request.startsWith("GET")) {
outputToClient.println("Wrong request\r\n"
+ "\r\n");
} else if (request.startsWith("exit")) {
break;
} else if (request.startsWith("pwd")) {
File file = new File(System.getProperty("user.dir"));
outputToClient.print("Status OK\r\n"
+ "Lines 1\r\n"
+ "\r\n"
+ "Working dir: " + file.getName() + "\r\n");
} else if (request.startsWith("list")) {
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
outputToClient.print("Status OK\r\n"
+ "Files " + files.length + "\r\n"
+ "\r\n"
+ Arrays.toString(files).substring(1, Arrays.toString(files).length() - 1) + "\r\n");
} else if (request.startsWith("GET")) {
String filename = request.substring(4);
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
if (fileExists(files, filename)) {
file = new File(filename);
int fileSize = (int) file.length();
outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
fileSize, filename);
outputToClient.flush();
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[(1 << 7) - 1];
int bytesRead = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
}
os.close();
fis.close();//NPE is happening here.
} else {
outputToClient.print("Status 400\r\n"
+ "File " + filename + " not found\r\n"
+ "\r\n");
outputToClient.flush();
}
}
outputToClient.flush();
}
} catch (IOException e) {
System.err.println(e);
}
finally{
os.close();
}
}
}
}
UPDATE: Even if I remove the fis.close(); line from the server side, it shows java.net.SocketException: socket closed error.
The original problem is that you are using a try-with-resources block with an assigned variable with the same name as one of your class member variables. Removing the following line will remove the NPE:
fis.close();
The SocketException is being caused by the line:
os.close();
According to the documentation of Socket::getOutputStream:
Closing the returned OutputStream will close the associated socket.
Therefore, moving the line os = socket.getOutputStream(); to just below the line socket = serverSocket.accept(); line, and also moving os.close() to a finally block after your final catch block should solve this issue.
The socket represented by fis is null.
To correct, use this:
if (fis != null) fis.close;
try (FileInputStream fis = new FileInputStream(file))
In this line you are creating a new FileInputStream and using it, and it is not your FileInputStream field, declared before. This fis exists only on the "try" block. When you try to close your fis os.close(); you are trying to close your fis field, not the fis declared in the try.
Use this, instead:
try (fis = new FileInputStream(file)). With this you are instantiating a new FileInputStream in your field, not in a new variable.

JAVA HTTP/1 implementation null java.lang.NullPointerException socket programming and file not found every time

I am implementing HTTP 1 protocol in java using socket programming. I got output but after listening one request the server gives error like
null
java.lang.NullPointerException
at httpRequest.processRequest(httpRequest.java:24)
at httpRequest.run(httpRequest.java:119)
at java.lang.Thread.run(Unknown Source)
This is copy of my output from eclipse
Waiting for connection
Connection Established
Waiting for connection
Connection Established
Waiting for connection
GET / HTTP/1.1
Host: localhost:5358
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
null
java.lang.NullPointerException
This is my source code.
import java.net.*;
import java.io.*;
import java.util.*;
public final class webServer
{
public static void main(String arg[]) throws Exception
{
int port=5358;
ServerSocket listen = new ServerSocket(port);
while(true)
{
System.out.println("Waiting for connection\n\n");
Socket server = listen.accept();
System.out.println("Connection Established\n\n");
httpRequest request = new httpRequest(server);
Thread thread = new Thread(request);
thread.start();
}
}
}
class httpRequest implements Runnable
{
final String CRLF = "\r\n";
Socket socket;
public httpRequest(Socket socket) throws Exception
{
this.socket = socket;
}
public void processRequest() throws Exception
{
InputStream is = socket.getInputStream();
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String requestLine = br.readLine();
System.out.println("\n\n\n" + requestLine);
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0)
{
System.out.println(headerLine);
}
StringTokenizer tokens = new StringTokenizer(requestLine);
tokens.nextToken(); // skip over the method, which should be "GET"
String fileName = tokens.nextToken();
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
FileInputStream fis = null;
boolean fileExists = true;
try
{
fis = new FileInputStream(fileName);
}
catch (FileNotFoundException e)
{
fileExists = false;
}
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists)
{
statusLine = "HTTP/1.0 200 OK" + CRLF ;
contentTypeLine = "Content-type: " + contentType( fileName ) + CRLF;
}
else
{
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
contentTypeLine = "Content-type: " + "text/html" + CRLF;
entityBody = "<HTML>" +
"<HEAD><TITLE>Not Found</TITLE></HEAD>" +
"<BODY>Not Found</BODY></HTML>";
}
// os.close();
//br.close();
//socket.close();
// Send the status line.
os.writeBytes(statusLine);
// Send the content-type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes(entityBody);
}
}
private void sendBytes(FileInputStream fis, DataOutputStream os) throws Exception {
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while((bytes = fis.read(buffer)) != -1 ) {
os.write(buffer, 0, bytes);
}
}
private String contentType(String fileName)
{
if (fileName.endsWith(".htm") || fileName.endsWith(".html"))
{
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))
{
return "image/jpeg";
}
if (fileName.endsWith(".gif"))
{
return "image/gif";
}
if (fileName.endsWith(".txt"))
{
return "text/plain";
}
if (fileName.endsWith(".pdf"))
{
return "application/pdf";
}
return "application/octet-stream";
}
public void run()
{
try
{
processRequest();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
while ((headerLine = br.readLine()).length() != 0)
above line is buggy, br.readLine can give you null value on which you are trying to run length method. It will throw null pointer. Change it something like below
while((headerLine = br.readLine()) != null)

Java Peer-to-Peer networking application - homework

I'm creating a p2p application in Java for file sharing. Each peer node will be running on my machine on a different port and listen for a request. but the problem I'm running into is when an instance of PeerNode is created my code runs into an infinite loop. Following is my code for PeerNode. Is this how I should create each node and have them listen for incoming requests?
Following code represents one peer node:
public class PeerNode
{
private int port;
private ArrayList<PeerNode> contacts;
PeerNode preNode;
PeerNode postNode;
private String directoryLocation = "";
PeerNode(int port)
{
this.port = port;
this.setDirectoryLocation( port+"");
startClientServer( port );
}
private void sendRequest(String fileName, String host, int port) throws UnknownHostException, IOException
{
Socket socket = new Socket(host, port);//machine name, port number
PrintWriter out = new PrintWriter( socket.getOutputStream(), true );
out.println(fileName);
out.close();
socket.close();
}
private void startClientServer( int portNum )
{
try
{
// Establish the listen socket.
ServerSocket server = new ServerSocket( 0 );
System.out.println("listening on port " + server.getLocalPort());
while( true )
{
// Listen for a TCP connection request.
Socket connection = server.accept();
// Construct an object to process the HTTP request message.
HttpRequestHandler request = new HttpRequestHandler( connection );
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
System.out.println("Thread started for "+ portNum);
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And following class creates all the nodes and connects them:
public class MasterClientServer
{
public static void main( String [] args )
{
int count = 10;
ArrayList<PeerNode> arrayOfNodes = createNodes( count );
}
public static ArrayList<PeerNode> createNodes( int count)
{
System.out.println("Creating a network of "+ count + " nodes...");
ArrayList< PeerNode > arrayOfNodes = new ArrayList<PeerNode>();
for( int i =1 ; i<=count; i++)
{
arrayOfNodes.add( new PeerNode( 0 ) ); //providing 0, will take any free node
}
return arrayOfNodes;
}
}
public class HttpRequestHandler implements Runnable
{
final static String CRLF = "\r\n";
Socket socket;
public HttpRequestHandler(Socket socket) throws Exception
{
this.socket = socket;
}
#Override
public void run()
{
try
{
processRequest();
}
catch (Exception e)
{
System.out.println(e);
}
}
/*
* Gets a request from another node.
* Sends the file to the node if available.
*/
private void processRequest() throws Exception
{
/*DataOutputStream os = new DataOutputStream(socket.getOutputStream());
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// Get the request line of the HTTP request message.
String requestLine = br.readLine();
// Extract the filename from the request line.
// In Get request, the second token is the fie name
String[] tokens = requestLine.split(" ");
String fileName = tokens[1];
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try
{
fis = new FileInputStream(fileName);
}
catch (FileNotFoundException e)
{
fileExists = false;
}
// construct the response Message
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists)
{
statusLine = "HTTP/1.1 200 OK" + CRLF;
contentTypeLine = "Content-Type: " + contentType(fileName) + CRLF;
}
else
{
statusLine = "HTTP/1.1 404 Not Found" + CRLF;
contentTypeLine = "Content-Type: text/html" + CRLF;
entityBody = "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY>Error 404: Page Not Found</BODY></HTML>";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes(entityBody);
}
// Close streams and socket.
os.close();
br.close();
socket.close();
}
private static void sendBytes(FileInputStream fis, OutputStream os)
throws Exception
{
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while ((bytes = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytes);
}*/
}
private static String contentType(String fileName)
{
if (fileName.endsWith(".htm") || fileName.endsWith(".html"))
{
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))
{
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
if (fileName.endsWith(".ram") || fileName.endsWith(".ra"))
{
return "audio/x-pn-realaudio";
}
return "application/octet-stream";
}
}
Your PeerNode constructor never returns since it is busy accepting new connections. Hence your loop in createNodes only creates the first PeerNode instance. You can solve this by calling startClientServer in a new thread:
new Thread(new Runnable() {
public void run() {
startClientServer( port );
}
}.start();

Categories

Resources