I wrote Java program that uses Sockets in order to receive the http request from the client (please NOTE: Everything happens in the localhost) and my program using the Socket library outputs the header response and the html body if GET has been chosen by the client. So let me put in an example:
I run my server at port 12345 and my source file consists of the java file and the example html file.
Client, using the web browser enters: http://localhost:12345/path-to-source/File.html
Server gets input via InputStream: GET path-to-file/File.html HTTP/1.1
So it responds via OutputStream the HTTP status (200 OK), the other fields like Content-type, content-length and then the body (html source code).
For some reason, it outputs nothing to the browser. On the other hand, when I use terminal and type:
curl -s -I -X GET localhost:12345/path-to-file/File.html
It actually displays to the terminal to the client the correct output:
HTTP/1.1 200 OK
Host: localhost:12345
User-Agent: curl/7.51.0
Accept: */*
Content-Type: */*
Content-Length: 18900
But for some reason, the Accept is / event though I have expected text/html
So to be clear, my desired output is:
HTTP/1.1 200 OK
Accept: text/html
Content-Type: text/html
Content-Length: 18900
Content: .....
Can you look at my code and spot what am I doing wrong here? Also, I don't want to use other libraries as I am trying to understand how socket works and the low level:
public class WebServerMain {/** This method prints to the output stream (to the client) the necessary fields, like Content type, Content length and etc.
It only serves GET and HEAD requests and if the file exists (200). **/
public static void printToClient(int length,BufferedReader in, PrintWriter out) {
String request;
String response;
try {
while ((request = in.readLine()) != null) {
out.println(request);
if (request.split(" ")[0].equals("Accept:")) {
response = request.split(" ")[1].split(",")[0];
out.print("Content-Type: " + response + "\r\n");
out.print("Content-Length: " + length + "\r\n");
break;
}
}
} catch(IOException e){
System.err.println("Usage: java WebServerMain <document_root> <port>");
}
}
public static void main(String args[]) {
try {
String cd = "/"+ args[0]; // This is the string that user chooses to pick the directory.
int port;
port = Integer.parseInt(args[1]);
int length = 0; // In order to find the length of the content.
String request;
String response;
final String dir = System.getProperty("user.dir");
System.out.println("current dir = " + dir+cd);
// Create a ServerSocket to listen on that port.
ServerSocket ss = new ServerSocket(port);
// Now enter an infinite loop, waiting for & handling connections.
for (;;) {
// Wait for a client to connect. The method will block;
// when it returns the socket will be connected to the client
Socket socket = ss.accept();
// Get input and outputstreams to talk to the client
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
String userInput = in.readLine();
System.out.println(userInput);
System.out.println("Final dir is " + dir+userInput.split(" ")[1]);
String str;
String content = "";
if(!userInput.split(" ")[0].equals("GET") && !userInput.split(" ")[0].equals("HEAD")){
out.println("HTTP/1.1 501 Not Implemented");
} // Checking, if the user chose correct options, GET or HEAD. If neither, we shall print 501 status code.
else {
try {
BufferedReader readContent = new BufferedReader(new FileReader(dir+cd+userInput.split(" ")[1]));
while ((str = readContent.readLine()) != null) {
content += str;
} // If the file exists, we are reading its content to the string called content. String str is a temporary string.
length = content.length();
out.println(userInput.split(" ")[2] + " 200 OK");
} catch (FileNotFoundException f) {
out.println(userInput.split(" ")[2] + " 404 Not Found");
out.close(); // Flush and close the output stream
in.close(); // Close the input stream
socket.close(); // Close the socket itself
}
if (userInput.split(" ")[0].equals("GET")) {
printToClient(length, in, out);
out.println(content);
} else if (userInput.split(" ")[0].equals("HEAD")) {
printToClient(length, in, out);
}
}
// Close socket, breaking the connection to the client, and
// closing the input and output streams
out.close(); // Flush and close the output stream
in.close(); // Close the input stream
socket.close(); // Close the socket itself
} // Now loop again, waiting for the next connection
}
// If anything goes wrong, print an error message
catch (IOException e) {
System.err.println(e.getMessage());
}
catch (ArrayIndexOutOfBoundsException a){
System.err.println("Usage: java WebServerMain <document_root> <port>");
}
}
}
You can check the headers sent by the web browser using the developer console (right-click -> inspect and then go to the network tab). There you can see what is beeing sent.
Regarding the code you have posted I would restructure two parts:
1) In the loop, after accepting a connection, branch the reading and responding logic to a new thread.
2) Instead of scattering the in.readln() throught the code, read everything in one place and then parse it.
If you go this way, it will be easy to log the whole request you received and see if your assumptions regarding what is reaching the server are correct.
public static void printToClient(...
...
out.print("Content-Type: " + response + "\r\n");
out.print("Content-Length: " + length + "\r\n");
break;
public static void main(String args[]) {
...
printToClient(length, in, out);
out.println(content);
There seems to be no \r\n (i.e. empty line) at the end of the HTTP response header which is required in HTTP/1.x to signal the end of the HTTP header. This means that you send an invalid response.
Apart from that your dealing with the request looks very strange for me:
The client is not required to send an Accept header (although at least the browsers do), yet you require one.
For whatever reason you reflect all request headers up to and including the Accept header back to the client, even if these headers don't make any sense in the response.
You send the status line only with println which ends the line with \n only instead the required \r\n.
Your error responses (404, 501) miss the \r\n at the end of the header top, which is required even if no body follows.
Related
I have a software driver which communicates with a third-party controller; I have an API for using the latter but no visibility of its source code, and the supplier is not co-operative in trying to improve things!
The situation is as follows.
To send a request to the controller, I send an XML packet as the content of an HTTP POST to a servlet, which then sends me the response. The original code, implemented by a previous developer, works stably using java.net.Socket. However, our driver is implemented such that a new socket is created for EVERY request sent and, if the driver gets busy, the third-party controller struggles to keep up in terms of socket handling. In fact, their support guy said to me: "You really need to leave 5 seconds between each request...". This simply isn't commercially acceptable.
To improve performance, I wanted to try leaving our end of the socket open and reusing the socket pretty much indefinitely (given that connections can drop unexpectedly of course, but that's the least of my concerns and is manageable). However, whatever I seem to do, the effect is that if I use Comms.getSocket(false), a new socket is created for each request and everything works OK but bottlenecks when busy. If I use Comms.getSocket(true), the following happens:
Controller is sent first request
Controller responds to first request
Controller is sent second request (maybe 5 seconds later)
Controller never responds to second request or anything after it
postRequest() keeps getting called: for the first 12 seconds, the console outputs "Input shut down ? false" but, after that, the code no longer reaches there and doesn't get past the bw.write() and bw.flush() calls.
The controller allows both HTTP 1.0 and 1.1 but their docs say zilch about keep-alive. I've tried both and the code below shows that I've added Keep-Alive headers as well but the controller, as server, I'm guessing is ignoring them -- I don't think I have any way of knowing, do I ? When in HTTP 1.0 mode, the controller certainly returns a "Connection: close" but doesn't do that in HTTP 1.1 mode.
The likelihood is then that the server side is insisting on a "one socket per request" approach.
However, I wondered if I might be doing anything wrong (or missing something) in the following code to achieve what I want:
private String postRequest() throws IOException {
String resp = null;
String logMsg;
StringBuilder sb = new StringBuilder();
StringBuilder sbWrite = new StringBuilder();
Comms comms = getComms();
Socket socket = comms.getSocket(true);
BufferedReader br = comms.getReader();
BufferedWriter bw = comms.getWriter();
if (null != socket) {
System.out.println("Socket closed ? " + socket.isClosed());
System.out.println("Socket bound ? " + socket.isBound());
System.out.println("Socket connected ? " + socket.isConnected());
// Write the request
sbWrite
.append("POST /servlet/receiverServlet HTTP/1.1\r\n")
.append("Host: 192.168.200.100\r\n")
.append("Connection: Keep-Alive\r\n")
.append("Keep-Alive: timeout=10\r\n")
.append("Content-Type: text/xml\r\n")
.append("Content-Length: " + requestString.length() + "\r\n\r\n")
.append(requestString);
System.out.println("Writing:\n" + sbWrite.toString());
bw.write(sbWrite.toString());
bw.flush();
// Read the response
System.out.println("Input shut down ? " + socket.isInputShutdown());
String line;
boolean flag = false;
while ((line = br.readLine()) != null) {
System.out.println("Line: <" + line + ">");
if (flag) sb.append(line);
if (line.isEmpty()) flag = true;
}
resp = sb.toString();
}
else {
System.out.println("Socket not available");
}
return resp; // Another method will parse the response
}
To ease testing, I provide the socket using an extra Comms helper class and a method called getSocket(boolean reuse) where I can choose to always create a new socket or reuse the one that Comms creates for me, as follows:
public Comms(String ip, int port) {
this.ip = ip;
this.port = port;
initSocket();
}
private void initSocket() {
try {
socket = new Socket(ip, port);
socket.setKeepAlive(true);
socket.setPerformancePreferences(1, 0, 0);
socket.setReuseAddress(true);
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
System.out.println("### CREATED NEW SOCKET");
}
catch (UnknownHostException uhe) {
System.out.println("### UNKNOWN HOST FOR SOCKET");
}
catch (IOException ioe) {
System.out.println("### SOCKET I/O EXCEPTION");
}
}
public BufferedReader getReader() { return br; }
public BufferedWriter getWriter() { return bw; }
public Socket getSocket(boolean reuse) {
if (! reuse) initSocket();
return socket;
}
Can anyone help ?
If we assume that keep-alive thing is working as expected, I think the line while ((line = br.readLine()) != null) is a faulty one, as this is kind of infinity loop.
readline() returns null when there is no more data to read, e.g. a EOF, or when server/client closes the connection, that will break-down your reusing socket solution, since an open stream will never cause a null to a readLine() call, but blocking.
You need to fix the alg about reading a response (why not using implemented http client?), checking content-length, and when read the amount of required data from body, go for next loop by keeping the socket alive.
After that setting flag to true, you have to know what kind of data should be read(considering mime/content-type), besides that, the length of data, so reading data using readLine() may not be a good practice here.
Also make sure server allow for persistence connection, by checking if it respects it by responsing the same connection:keep-alive header.
I'm trying to output hello when I enter enter localhost:9080/?say=hello. But I have no idea how to do it
public class MyServer {
public static void main(String args[])throws Exception{
ServerSocket ss=new ServerSocket(9080);
Socket client = ss.accept();
Scanner in =new Scanner(client.getInputStream());
// running infinite loop for getting
// client request
while (true){
String s = in.nextLine();
if (s==null || s.trim().length()==0)
break;
System.out.println(s);
}
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
String document = "<html><body>Salem</body></html>";
String response = "HTTP/1.1 200 OK\r\n" +
"Server: YarServer/2009-09-09\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: " + document.length() + "\r\n" +
"Connection: close\r\n\r\n";
out.println(response+document);
}
}
Of course this is a school work so I will not give you a ready-made working solution, just some hint.
Simplifying a lot, the HTTP protocol exchanges text strings between a client and a server. Your code already prints the strings that the browser sends to your server; take a look at the first line: it says
GET /?say=hello HTTP/1.1
"GET" is an "HTTP method", it is followed by the path of the server-side resource you requested (just a slash in this case) plus any request param (the part after the question mark) and the protocol version.
To perform a specific action for a specific path/param requested by the client, your code should examine the first line of text submitted by the browser (for example you should check for the presence of /?say=hello).
Furthermore, usuallly an HTTP server doesn't shut-down after the first request, so your code should contain another infinite loop to wait for another connection after having served the first one. Your code should also close() the client socket after you have sent the response to the browser.
I am writing a web client. I have the following code.
public class Connection extends Thread{
public final static int PORT = 1337;
private ServerSocket svrSocket = null;
private Socket con = null;
public Connection(){
try{
svrSocket = new ServerSocket(PORT);
System.out.println("Conected to: " + PORT);
}catch(IOException ex)
{
System.err.println(ex);
System.out.println("Unable to attach to port");
}
}
public void run(){
while(true)
{
try{
con = svrSocket.accept();//on this part the program stops
System.out.println("Client request accepted");
PrintWriter out = new PrintWriter(con.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
out.println("GET /<index.html> HTTP/1.1");
out.println("***CLOSE***");
System.out.println(in.readLine());
/*
String s;
while((s = in.readLine()) != null)
{
System.out.println(s);
}*/
out.flush();
out.close();
in.close();
con.close();
System.out.println("all closed");
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
}
The run method will be used latter on. That I have is a file called index.html. This file is in the same file as the java code. What I am trying to do with the request is send the HTML file. But if I run this program on a web browser localhost:1337 the following gets displayed.
GET /<index.html> HTTP/1.1
***CLOSE***
This should not get displayed. The page that results of the HTML code in the index.html should get displayed.
Index.html code:
<html>
<head>
<title> </title>
</head>
<body bgcolor = "#ffffcc" text = "#000000">
<h1>Hello</h1>
<p>This is a simple web page</p>
</body>
</html>
How do I get this html page to display in the browser?
Thank you
t seems that all is good on your code, it seems you need to read the HTTP header from the input stream so you can get the requested file name and then use the Socket output stream to write the response from the file.
OutputStream output = con.getOutputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String fileName = readHeader(in);
String baseDir = System.getProperty("my.base.dir", "/home/myname/httpserver");
boolean exist = true;
InputStream fileIn = null;
try {
File requestedFile = new File(baseDir, fileName);
fileIn = new FileInputStream(requestedFile);
} catch(Exception e){
exist = false;
}
String server = "Java Http Server";
String statusLine = null;
String typeLine = null;
String body = null;
String lengthLine = "error";
if (exist) {
statusLine = "HTTP/1.0 200 OK" + "\r\n";
//get content type by extension
typeLine = "Content-type: html/text \r\n";
lengthLine = "Content-Length: " + (new Integer(fileIn.available())).toString() + "\r\n";
} else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
typeLine = "text/html";
body = "<HTML>" + "<HEAD><TITLE>404</TITLE></HEAD>" + "<BODY>404 Not Found"+"</BODY></HTML>";
}
output.write(statusLine.getBytes());
output.write(server.getBytes());
output.write(typeLine.getBytes());
output.write(lengthLine.getBytes());
output.write("\r\n".getBytes());
if (exist) {
byte[] buffer = new byte[1024];
int bytes = 0;
while ((bytes = fileIn.read(buffer)) != -1) {
output.write(buffer, 0, bytes);
}
} else {
output.write(body.getBytes());
}
//close sreams
You are confusing a couple of things. First of all: what you are writing is a server, not a client.
Second: You are not following the HTT Protocol.
The line GET /<index.html> HTTP/1.1 (which is wrong, it should be GET /index.html HTTP/1.1) is a request that is sent by the client (like a web browser). Instead, it is your server sending this.
A quick solution:
Instead of sending this static text (the line with the GET and the one with the ***CLOSE***), read the content of your index.html file and print it to your out stream.
EDIT: Here's a quick overview of the http data flow:
The client (e.g. a browser) connects to the server
The client sends it's request, something like
GET /theFileIWant.html HTTP/1.1\r\n
Host: localhost\r\n
\r\n
at this point, the client usually stops sending anything and waits for the server to respond. That is called the "request/response" model.
The server reads the request data and finds out what it has to do.
The output (in this case: a file's content) is sent to the client, preceded by HTTP response headers.
The connection can be kept open or closed, depending on the HTTP headers of both client's request and server's response.
so i made a little code that can download 4chan pages. i get the raw HTML page and parse it for my need. the code below was working fine but it suddenly stopped working. when i run it the server does not accept my request it seems its waiting for something more. however i know that HTTP request is as below
GET /ck HTTP/1.1
Host: boards.4chan.org
(extra new line)
if i change this format in anyway i revive "400 bad request" status code. but if i change HTTP/1.1 to 1.0 the server responses in "200 ok" status and i get the whole page. so this makes me thing the error is in the host line since that became mandatory in HTTP/1.1. but still i cannot figure out what exactly need to be changed.
the calling function simply this, to get one whole board
downloadHTMLThread( "ck", -1);
or for a specific thread u just change -1 to that number. for example like for the link below will have like below.
//http://boards.4chan.org/ck/res/3507158
//url.getDefaultPort() is 80
//url.getHost() is boards.4chan.org
//url.getFile() is /ck/res/3507158
downloadHTMLThread( "ck", 3507158);
any advise would be appreciated, thanks
public static final String BOARDS = "boards.4chan.org";
public static final String IMAGES = "images.4chan.org";
public static final String THUMBS = "thumbs.4chan.org";
public static final String RES = "/res/";
public static final String HTTP = "http://";
public static final String SLASH = "/";
public String downloadHTMLThread( String board, int thread) {
BufferedReader reader = null;
PrintWriter out = null;
Socket socket = null;
String str = null;
StringBuilder input = new StringBuilder();
try {
URL url = new URL(HTTP+BOARDS+SLASH+board+(thread==-1?SLASH:RES+thread));
socket = new Socket( url.getHost(), url.getDefaultPort());
reader = new BufferedReader( new InputStreamReader( socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
out.println( "GET " +url.getFile()+ " HTTP/1.1");
out.println( "HOST: " + url.getHost());
out.println();
long start = System.currentTimeMillis();
while ((str = reader.readLine()) != null) {
input.append( str).append("\r\n");
}
long end = System.currentTimeMillis();
System.out.println( input);
System.out.println( "\nTime: " +(end-start)+ " milliseconds");
} catch (Exception ex) {
ex.printStackTrace();
input = null;
} finally {
if( reader!=null){
try {
reader.close();
} catch (IOException ioe) {
// nothing to see here
}
}
if( socket!=null){
try {
socket.close();
} catch (IOException ioe) {
// nothing to see here
}
}
if( out!=null){
out.close();
}
}
return input==null? null: input.toString();
}
Try using Apache HttpClient instead of rolling your own:
static String getUriContentsAsString(String uri) throws IOException {
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(new HttpGet(uri));
return EntityUtils.toString(response.getEntity());
}
If you are doing this to really learn the internals of HTTP client requests, then you might start by playing with curl from the command line. This will let you get all your headers and request body squared away. Then it will be a simple matter of adjusting your request to match what works in curl.
By the code I think that you are sending 'HOST' instead of 'Host'. Since this is a compulsory header in http/1.1, but ignored in http/1.0, that might be the problem.
Anyway, you could use a program to capture the packet sent (i. e. wireshark), just to make sure.
Using println is quite useful, but the line separator appended to the command depends on the system property line.separator. I think (although I'm not sure) that the line separator used in http protocol has to be '\r\n'. If you're capturing the packet, I think it'd be a good idea to check that each line sent ends with '\r\n' (bytes x0D0A) (just in case your os line separator is different)
Use www.4chan.org as the host instead. Since boards.4chan.org is a 302 redirect to www.4chan.org, you won't be able to scrape anything from boards.4chan.org.
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
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.
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);
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.
Check this out, it's already done for you:
http://www.mcwalter.org/technology/java/httpd/tiny/index.html
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'.