I am trying to send this htm file to a web browser and have the browser display the contents of the file. When I run my code, all that happens is the browsers displays the name of the htm file and nothing else.
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String input = in.readLine();
while (!input.isEmpty())
{
System.out.println("\tserver read a line: " + input);
input = in.readLine();
}
System.out.println("");
File myFile = new File ("hello.htm");
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html");
out.println("\r\n");
out.write(myFile);
out.flush();
out.close();
}
catch(Exception e)
{
System.out.println("\ncaught exeception: " + e + "\n");
}
You need to actually write the contents of the file to the stream:
...
BufferedReader in2 = new BufferedReader(new FileReader(myFile));
out.write("HTTP/1.1 200 OK\r\n");
out.write("Content-Type: text/html\r\n");
//Tell the end user how much data you are sending
out.write("Content-Length: " + myFile.length() + "\r\n");
//Indicates end of headers
out.write("\r\n");
String line;
while((line = in2.readLine()) != null) {
//Not sure if you should use out.println or out.write, play around with it.
out.write(line + "\r\n");
}
//out.write(myFile); Remove this
out.flush();
out.close();
...
The above code is just an idea of what you really should be doing. It takes into account the HTTP protocol.
Related
Right now, I'm trying to make a server that can display messages to the client when they connect (through localhost). When I connect through telnet, it gives me weird indentation. The code for the server is:
private ServerSocket middleman;
private int port = 8080;
private Socket client;
protected void createSocketServer()
{
try
{
while (true){
middleman = new ServerSocket(port);
client = middleman.accept();
middleman.close();
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String line;
//Client stuff
DataOutputStream dOut = new DataOutputStream(client.getOutputStream());
while((line = in.readLine()) != null)
{
System.out.println("echo: " + line);
dOut.writeByte(1);
dOut.writeUTF("Good day to you user. Here is a selection of poems " + "\n");
dOut.writeUTF("1. Cupcake Poem" + "\n");
dOut.flush();
//Response
if(line.equals("cupcake")){
try{
FileReader fileReader = new FileReader(poem);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String poemLine;
while((poemLine = bufferedReader.readLine()) != null){
stringBuffer.append(poemLine);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file:");
//System.out.println(stringBuffer.toString());
dOut.writeUTF(stringBuffer.toString());
dOut.flush();
} catch(IOException e){
e.printStackTrace();
}
}
else{
System.out.println("wrong!, the line is:" + line);
}
}
}
}
catch(IOException e)
{
System.out.println(e);
}
}
On the client side, I'll open the command prompt and type telnet localhost 8080 then I'll type something like "fish". It will print
[?]Good day to you user. here is a selection of poems
1. Cupcake Poem
Why does it do this? If I type "cupcake" on client, it will read the file, but have weird spacing. Is this something to do with Telnet?
For telnet the correct end-of-line sequence is "\r\n". Newline by itself will only go down to the next line, but it will not back up to the first column, which what the carriage-return does.
Also note that the order matters, the telnet specifications says that it has to be "\r\n", in that order.
Also, you don't have to append the output with the newline-sequence like you do. You can write it all as a single string:
dOut.writeUTF("1. Cupcake Poem\r\n");
I am working on an Android application that establish a mini-http server to send kind of files to clients. Clients send the request and this application respond with a regular http response (so it contains header and the file content).
I have a piece of code that works with text files.
os = new PrintWriter(socket.getOutputStream(), true);
String filename = "index.html";
File file = new File(Environment.getExternalStorageDirectory().toString()+"/FileShare/",filename);
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {...}
os.print("HTTP/1.0 200" + "\r\n");
os.print("Content type: " + getMimeType(filename) + "\r\n");
os.print("Content length: " + text.length() + "\r\n");
os.print("\r\n");
os.print(text + "\r\n");
os.flush();
socket.close();
So my question is how to put binary data to the http content?
Thanks in advance.
I am writing a Client/Server program. When I tried to read String from client using scanner.nextLine() it does not wait for to write the text on console and process the next statement. I am writing program in BInary I/O because it is more efficient then text I/O.
DataInputStream fromServer = null;
DataOutputStream toServer = null;
Scanner scanner = new Scanner(System.in);
try{
socket = new Socket("localhost",8000);
toServer = new DataOutputStream
(socket.getOutputStream());
fromServer = new DataInputStream
( socket.getInputStream());
}
catch(IOException e){
System.out.println(" Error in connection: " + e);
e.printStackTrace();
}
System.out.println("Connection is successfully Established...");
try{
//This does not processing
setText = scanner.nextLine();
toServer.writeUTF(setText);
toServer.flush();
// Get area from the server
double area = fromServer.readDouble();
// Display to the text area
System.out.println("Text from Client " + setText + "\n");
System.out.println("Response from server " + area + '\n');
}
catch(IOException e){
System.out.println(" Error in connection: " + e);
e.printStackTrace();
}
The output is:
Text from Client
Response from server 45.22
As you can see the program does not take input from the console
If I used next() instead of nextLine() then it runs fine, but I want to read the line of text up to enter key.
I was trying to send plain text through Socket. So I found a post in StackOverflow, I followed it and I guess it that I did it write However, How can I accept that plain text as string in the client?
I used BufferedReader() and InputStreamReader() class, but exception has been thrown.
Exception : exception java.net.SocketException: Broken pipe
Here is the code:
Server:
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
osw.write(fileName, 0, fileName.length());
Client:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
br.close();
Some help would be great. :) Thank you.
Client side code:
public void soc_client() throws Exception {
long time = System.currentTimeMillis();
long totalRecieved = 0;
try {
Socket sock = new Socket("172.16.27.106", 55000);
System.out.println("Hello Client");
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
File outputFile = new File(fileName + "");
br.close(); // CLOSING BufferedReader
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
totalRecieved += bytesRead;
System.out.println("Recieved " + (totalRecieved / 1024)
+ " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000)
+ " seconds");
}
fileOutputStream.close();
sock.close();
} catch (Exception e) {
System.out.println("Exception " + e);
} finally {
System.out.println("Recieved " + totalRecieved + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}
You're reading a line but you aren't sending a line, and you aren't closing the OutputWriter either. So readLine() will block forever waiting for a line terminator or an EOS that is never coming.
Add a newline to the message.
Close the OutputWriter.
Well to use sockets to send and transfer text in client server fashion , i'm posting a simple basic code , which upon running send a HELLO WORLD response to client.
//Server Side
ServerSocket server= new ServerSocket(1166); // //1166 -port no. u can use any other too.
Socket s= server.accept(); // makes a connection whenever a client requests.
OutputStream os= socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Hello World");
dos.close();
// Client Side
Socket socket= new Socket("Ip address of you server" , 1166) ;
InputStream is= new InputStream();
DataInputStream dis = new DataInputStream(is);
String msg=dis.readUTF();
System.out.println(msg);
dis.close();
now after you run the code once on server computer , then run the client side code and the server will now respond you with Hello World.
I'm trying to create a simple server that accepts a request, and then writes the content of a file to the browser that sent the request. The server connects and writes to the socket. However my browser says
no data received
and doesn't display anything.
public class Main {
/**
* #param args
*/
public static void main(String[] args) throws IOException{
while(true){
ServerSocket serverSock = new ServerSocket(6789);
Socket sock = serverSock.accept();
System.out.println("connected");
InputStream sis = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(sis));
String request = br.readLine(); // Now you get GET index.html HTTP/1.1`
String[] requestParam = request.split(" ");
String path = requestParam[1];
System.out.println(path);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
File file = new File(path);
BufferedReader bfr = null;
String s = "Hi";
if (!file.exists() || !file.isFile()) {
System.out.println("writing not found...");
out.write("HTTP/1.0 200 OK\r\n");
out.write(new Date() + "\r\n");
out.write("Content-Type: text/html");
out.write("Content length: " + s.length() + "\r\n");
out.write(s);
}else{
FileReader fr = new FileReader(file);
bfr = new BufferedReader(fr);
String line;
while ((line = bfr.readLine()) != null) {
out.write(line);
}
}
if(bfr != null){
bfr.close();
}
br.close();
out.close();
serverSock.close();
}
}
}
Your code works for me (data shows up in the browser), if I use
http://localhost:6789/etc/hosts
and there is a file /etc/hosts (Linux filesystem notation).
If the file does not exist, this snippet
out.write("HTTP/1.0 200 OK\r\n");
out.write(new Date() + "\r\n");
out.write("Content-Type: text/html\r\n");
out.write("\r\n");
out.write("File " + file + " not found\r\n");
out.flush();
will return data that shows up in the browser: Note that I have explicitly added a call to flush() here. Make sure that out is flushed in the other case as well.
The other possibility is to reorder your close statements.
A quote from EJP's answer on How to close a socket:
You should close the outermost output stream you have created from the socket. That will flush it.
This is especially the case if the outermost output stream is (another quote from the same source):
a buffered output stream, or a stream wrapped around one. If you don't close that, it won't be flushed.
So out.close() should be called before br.close().