3

I have created the following test server using java:

   import java.io.*;
import java.net.*;

class tcpServer{
    public static void main(String args[]){
        ServerSocket s = null;
        try{
            s = new ServerSocket(7896);
            //right now the stream is open.
            while(true){
                Socket clientSocket = s.accept();
                Connection c = new Connection(clientSocket);
                //now the connection is established
            }
        }catch(IOException e){
            System.out.println("Unable to read: " + e.getMessage());
        }
    }
}
class Connection extends Thread{
    Socket clientSocket;
    BufferedReader din;
    OutputStreamWriter outWriter;

    public Connection(Socket clientSocket){
        try{
            this.clientSocket = clientSocket;
            din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "ASCII"));
            outWriter = new OutputStreamWriter(clientSocket.getOutputStream());
            this.start();
        }catch(IOException e){
            System.out.println("Connection: " + e.getMessage());
        }   
    }
    public void run(){
        try{
        String line = null;
        while((line = din.readLine())!=null){
            System.out.println("Read" + line);
            if(line.length()==0)    
                break;
        }
        //here write the content type etc details:
        System.out.println("Someone connected: " + clientSocket);
        outWriter.write("HTTP/1.1 200 OK\r\n");
        outWriter.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
        outWriter.write("Expires: -1\r\n");
        outWriter.write("Cache-Control: private, max-age=0\r\n");
        outWriter.write("Content-type: text/html\r\n");
        outWriter.write("Server: vinit\r\n");
        outWriter.write("X-XSS-Protection: 1; mode=block\r\n");
        outWriter.write("<html><head><title>Hello</title></head><body>Hello world from my server</body></html>\r\n");
        }catch(EOFException e){
            System.out.println("EOF: " + e.getMessage());
        }
        catch(IOException e){
            System.out.println("IO at run: " + e.getMessage());
        }finally{
            try{
                            outWriter.close();  
                clientSocket.close();
            }catch(IOException e){
                System.out.println("Unable to close the socket");
            }
        }
    }
}

Now i want this server to respond to my browser. that's why i gave url: http://localhost:7896 and as a result i receive at the server side:

ReadGET / HTTP/1.1
ReadHost: localhost:7896
ReadConnection: keep-alive
ReadCache-Control: max-age=0
ReadAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
ReadUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
ReadAccept-Encoding: gzip,deflate,sdch
ReadAccept-Language: en-US,en;q=0.8
ReadAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
ReadCookie: test_cookie=test cookie
Read
Someone connected: Socket[addr=/0:0:0:0:0:0:0:1,port=36651,localport=7896]

And a blank white screen at my browser and source code also blank. In google chrome browser.

So can anyone please tell me where i m wrong. actually i am new to this thing. so please correct me.

Thanks in advance

3
  • Ok this worked after adding one more \n after the headers. So thanks all for their support Commented Jan 11, 2011 at 9:12
  • Hey but still one thing that seems me odd that addr of browser being 0:0:0:0:0:0:0:1?? what this means Commented Jan 11, 2011 at 9:14
  • A pointer to you if you dont know already - "How Tomcat Works" by Budi Kurniawan , Paul Deck is a good start point. Commented Jan 11, 2011 at 10:00

5 Answers 5

6

You almost certainly don't want to be using DataOutputStream on the response - and writeUTF certainly isn't going to do what you want. DataOutputStream is designed for binary protocols, basically - and writeUTF writes a length-prefixed UTF-8 string, whereas HTTP just wants CRLF-terminated lines of ASCII text.

You want to write headers out a line at a time - so create an OutputStreamWriter around the socket output stream, and write to that:

writer.write("HTTP/1.1 200 OK\r\n");
writer.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");

etc.

You may want to write your own writeLine method to write out a line including the CRLF at the end (don't use the system default line terminator), to make the code cleaner.

Add a blank line between the headers and the body as well, and then you should be in reasonable shape.

EDIT: Two more changes:

Firstly, you should read the request from the client. For example, change din to a BufferedReader, and initialize it like this:

din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
                                               "ASCII"));

then before you start to write the output, read the request like this:

String line;
while ((line = din.readLine()) != null) {
    System.out.println("Read " + line);
    if (line.length() == 0) {
        break;
    }
}

EDIT: As noted in comments, this wouldn't be appropriate for a full HTTP server, as it wouldn't handle binary PUT/POST data well (it may read the data into its buffer, meaning you couldn't then read it as binary data from the stream). It's fine for the test app though.

Finally, you should also either close the output writer or at least flush it - otherwise it may be buffering the data.

After making those changes, your code worked for me.

Sign up to request clarification or add additional context in comments.

9 Comments

Hey jon i have done that as you told me but still getting the same error
@codeomnitrix: You need to close the writer before you close the socket - either that, or at least flush the writer. Will edit to mention that.
@codeomnitrix: You also need to read the request, at least from Chrome - I've edited the answer in include that. But note that the code in your question still doesn't have a blank line between the headers and the body. You need an empty line, e.g. outWriter.write("\r\n").
hey jon i have done that much and pretty good response as error gone away but still blank browser screen without any source code. And secondly would you please tell me what does that means by having close the writer earlier than socket.
The BufferedReader is not appropriate for reading incoming HTTP requests as soon as there is a message entity which might contain binary data (i.e. file upload of an image using PUT/POST).
|
2

If you're interested in learning the design and development of network servers like HTTP servers in Java, you might also have a look at this repo:

https://github.com/berb/java-web-server

It's a small HTTP server in Java I started for educational purposes. Though, it shouldn't be used in production or serious use cases yet. I'm still adding new features. It currently provides multi-threading, static file handling, Basic Authentication, logging and a in-memory cache.

EDIT

An obvious error in your code is the missing \r\n between your Response Header and your HTML. Just append an additional \r\n to your last header. Additionally, you must provide the content length, unless you're using Chuncked Encoding:

String out = "<html><head><title>Hello</title></head><body>Hello world from my server</body></html>\r\n";

outWriter.write("Content-Length: "+out.getBytes().length+"\r\n\r\n");
outWriter.write(out);

2 Comments

kk thanks partlycloudy that solved but what does the address or browser means which is 0:0:0:0:0:0:0:1
0:0:0:0:0:0:0:1 is localhost when using IPv6.
1
  • The HTTP protocol is ASCII based, exept the body which depends on the Content-Type header. So, no UTF-8 headers!
  • Headers and body must be separated by an empty line.
  • Why do you set your Transfert-Encoding to chuncked? Your body is not.

1 Comment

hey can you please give me a single line as an example how to write the headers
0

Check this out, it's already done for you:

http://www.mcwalter.org/technology/java/httpd/tiny/index.html

Comments

-1

I'm not sure if you have can use writeUTF instead, instead you may need to use writeBytes. Also, you need to terminate each line with a '\n'.

3 Comments

Hey i have made changes to my code but still getting the same error on google chrome. please check this
Hey abdullah i have edited the code and now its working but i found a blank output at google chrome with page source also blank
You need to terminate each header with \r\n. You don't need to line-terminate the body at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.