Bad Requests and Timeouts - java

I want to access an arbitrary webpage using sockets (as a learning mechanism for myself). The code below does not work, what am I doing wrong?
import java.net.*;
import java.io.*;
public class Example
{
public static void main(String args[]) throws Exception
{
Socket socket =
new Socket("www.google.com", 80);
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println("GET / HTTP/1.1 \\r\\n Host: www.google.com \\r\\n\\r\\n");
System.out.println("echo: " + reader.readLine());
}
}
}
After trying for a couple hours I was unable to figure out what exactly I was doing wrong. All I want is Google's or some other websites homepage. Can anyone help me?

You might try something like the following (using sockets)
package com.example.webpagesocket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class GetWebPageUsingSockets {
public static void main(String[] args) {
String urlString;
urlString = "www.google.com";
accessWeb(urlString);
}
private static void accessWeb(String urlString) {
String host;
String page;
int slashLoc;
// Set up encoding and decoding
Charset charset = Charset.forName("ISO-8859-1");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
if ((slashLoc = urlString.indexOf('/')) < 0) {
host = urlString;
page = "";
} else {
host = urlString.substring(0, slashLoc);
page = urlString.substring(slashLoc);
}
System.out.println("Accessing web page demonstration");
System.out.println("Host: '" + host + "' Page: '" + page + "'");
SocketChannel channel = null;
try {
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
CharBuffer charBuffer = CharBuffer.allocate(1024);
InetSocketAddress socketAddress = new InetSocketAddress(host, 80);
channel = SocketChannel.open();
channel.connect(socketAddress);
String request = "GET " + page + " \r\n\r\n";
channel.write(encoder.encode(CharBuffer.wrap(request)));
while ((channel.read(buffer)) != -1) {
buffer.flip();
decoder.decode(buffer, charBuffer, false);
charBuffer.flip();
System.out.println(charBuffer);
buffer.clear();
charBuffer.clear();
}
} catch (UnknownHostException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
} finally {
if (channel != null) {
try {
channel.close();
} catch (IOException ignored) {
}
}
}
System.out.println("\nDone.");
}
}

Edit : didn't notice the \ at first reading ...
It looks like you are continuously sending "GET / HTTP/1.1 \\r\\n Host: www.google.com \\r\\n\\r\\n" to the host (at each read). You'd better keeping it out of the loop and sent true carriage return + line feed and not printable chars \ r \ n :
out.println("GET / HTTP/1.1 \r\nHost: www.google.com\r\n\r\n");
String userInput;
while ((userInput = stdIn.readLine()) != null) {
You only start reading after sending your GET, but the socket will buffer data.

Related

Trouble writing to OutputStream socket

I am writing a simple web server program for class that sends files to the web browser on request. I have written as much as I could. The difficulty is getting the data written to the OutputStream. I don't know what I am missing. I couldn't get the simple request to show up on the web browser.
I wrote it to the "name" OutputStream but when I reload the tab in the browser with the URL: "http://localhost:50505/path/file.txt" or any other like that "localhost:50505" it doesn't show up what I wrote to the OutputStream "name". It is supposed to show that.
package lab11;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
public class main {
private static final int LISTENING_PORT = 50505;
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(LISTENING_PORT);
}
catch (Exception e) {
System.out.println("Failed to create listening socket.");
return;
}
System.out.println("Listening on port " + LISTENING_PORT);
try {
while (true) {
Socket connection = serverSocket.accept();
System.out.println("\nConnection from "
+ connection.getRemoteSocketAddress());
handleConnection(connection);
}
}
catch (Exception e) {
System.out.println("Server socket shut down unexpectedly!");
System.out.println("Error: " + e);
System.out.println("Exiting.");
}
}
public static void handleConnection(Socket sok) {
try {
// Scanner in = new Scanner(sok.getInputStream());
InputStream one = sok.getInputStream();
InputStreamReader isr = new InputStreamReader(one);
BufferedReader br = new BufferedReader(isr);
String rootDirectory = "/files";
String pathToFile;
// File file = new File(rootDirectory + pathToFile);
StringBuilder request = new StringBuilder();
String line;
line = br.readLine();
while (!line.isEmpty()) {
request.append(line + "\r\n");
line = br.readLine();
}
// System.out.print(request);
String[] splitline = request.toString().split("\n");
String get = null;
String file = null;
for (String i : splitline) {
if (i.contains("GET")) {
get = i;
String[] splitget = get.split(" ");
file = splitget[1];
}
}
}
OutputStream name = sok.getOutputStream();
Boolean doesexist = thefile.exists();
if (doesexist.equals(true)) {
PrintWriter response = new PrintWriter(System.out);
response.write("HTTP/1.1 200 OK\r\n");
response.write("Connection: close\r\n");
response.write("Content-Length: " + thefile.length() + "\r\n");
response.flush();
response.close();
sendFile(thefile, name);
} else {
System.out.print(thefile.exists() + "\n" + thefile.isDirectory() + "\n" + thefile.canRead());
}
}
catch (Exception e) {
System.out.println("Error while communicating with client: " + e);
}
finally { // make SURE connection is closed before returning!
try {
sok.close();
}
catch (Exception e) {
}
System.out.println("Connection closed.");
}
}
private static void sendFile(File file, OutputStream socketOut) throws
IOException {
InputStream in = new BufferedInputStream(new FileInputStream(file));
OutputStream out = new BufferedOutputStream(socketOut);
while (true) {
int x = in.read(); // read one byte from file
if (x < 0)
break; // end of file reached
out.write(x); // write the byte to the socket
}
out.flush();
}
}
So, I don't know what I really did wrong.
When I load the browser with localhost:50505 it just says can't connect or localhost refused to connect.
You are writing the HTTP response in System.out. You should write it in name, after the headers, in the body of the response. You probably want to describe it with a Content-Type header to make the receiver correctly show the file.

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".

Using socket to connet gmail and send gmail, but not work

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class SMTPDemo {
public static void main(String args[]) throws IOException,
UnknownHostException {
String msgFile = "file.txt";
String from = "java2s#java2s.com";
String to = "yourEmail#yourServer.com";
String mailHost = "yourHost";
SMTP mail = new SMTP(mailHost);
if (mail != null) {
if (mail.send(new FileReader(msgFile), from, to)) {
System.out.println("Mail sent.");
} else {
System.out.println("Connect to SMTP server failed!");
}
}
System.out.println("Done.");
}
static class SMTP {
private final static int SMTP_PORT = 25;
InetAddress mailHost;
InetAddress localhost;
BufferedReader in;
PrintWriter out;
public SMTP(String host) throws UnknownHostException {
mailHost = InetAddress.getByName(host);
localhost = InetAddress.getLocalHost();
System.out.println("mailhost = " + mailHost);
System.out.println("localhost= " + localhost);
System.out.println("SMTP constructor done\n");
}
public boolean send(FileReader msgFileReader, String from, String to)
throws IOException {
Socket smtpPipe;
InputStream inn;
OutputStream outt;
BufferedReader msg;
msg = new BufferedReader(msgFileReader);
smtpPipe = new Socket(mailHost, SMTP_PORT);
if (smtpPipe == null) {
return false;
}
inn = smtpPipe.getInputStream();
outt = smtpPipe.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
if (inn == null || outt == null) {
System.out.println("Failed to open streams to socket.");
return false;
}
String initialID = in.readLine();
System.out.println(initialID);
System.out.println("HELO " + localhost.getHostName());
out.println("HELO " + localhost.getHostName());
String welcome = in.readLine();
System.out.println(welcome);
System.out.println("MAIL From:<" + from + ">");
out.println("MAIL From:<" + from + ">");
String senderOK = in.readLine();
System.out.println(senderOK);
System.out.println("RCPT TO:<" + to + ">");
out.println("RCPT TO:<" + to + ">");
String recipientOK = in.readLine();
System.out.println(recipientOK);
System.out.println("DATA");
out.println("DATA");
String line;
while ((line = msg.readLine()) != null) {
out.println(line);
}
System.out.println(".");
out.println(".");
String acceptedOK = in.readLine();
System.out.println(acceptedOK);
System.out.println("QUIT");
out.println("QUIT");
return true;
}
}
}
I want learn about how to make smtp server to using socket.
I find this example code on this site.
When I write this code in Eclipse and compile but socekt smtpPipe is error.
Eclipse error message:
Resource leak : 'smtpPipe is never closed'.
I don't know how to solve this problem.
Eclipse error message : Resource leak : 'smtpPipe is never closed'
It says you are not closing the resource smtpPipe. The recommended practice is to close the resource when it is no longer needed. You can achieve this by calling smtpPipe.close() method.
One way of doing is to wrap your code around try and finally block. Read more about finally block here.
Example:
try {
....
smtpPipe = new Socket(mailHost, SMTP_PORT);
....
} finally {
if (smtpPipe != null)
smtpPipe.close();
}
Also, use the similar approach for other resources like InputStream and OutputStream

transformer to socket not working

Its driving me nuts trying days to grind this problem.
I am writing a java server to work with an android application. They communicate text string and xml.
Currently simple socket communication seems fine, however it breaks down when I tried to use transformer instead of simple println.
Server code as below
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class javamultithreadedserver implements Runnable {
Socket csocket;
static int listenport = 6021;
public static final String endOfCom = "endofcom";
String connectionname;
public javamultithreadedserver(Socket csocket, String connectionname) {
this.csocket = csocket;
this.connectionname = connectionname;
}
public static void main(String[] args) throws Exception {
int listentoport = 0;
//System.out.println(args.length);
if (args.length == 1){
listentoport = Integer.parseInt(args[0]);
} else{
listentoport = listenport;
}
ServerSocket ssock = new ServerSocket(listentoport);
System.out.println("Listening at port " + listentoport);
while (true) {
Socket sock = ssock.accept();
System.out.println("Connected. from: " + sock.getInetAddress().getHostAddress() + " " + sock.getInetAddress().getHostName() + " port: " + sock.getPort() + " " + sock.getInetAddress().getCanonicalHostName());
new Thread(new javamultithreadedserver(sock, sock.getInetAddress().getHostAddress() + " " + sock.getInetAddress().getHostName() + " " + sock.getInetAddress().getCanonicalHostName())).start();
}
}
#Override
public void run() {
try {
PrintWriter out = new PrintWriter(csocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(csocket.getInputStream()));
PrintStream pstream = new PrintStream (csocket.getOutputStream(), true);
String inputLine, outputLine;
System.out.println(connectionname + ": listening for query information.");
while ((inputLine = in.readLine()) != null) {
System.out.println(connectionname + ": " + inputLine);
//out.write("received something");
DBQuery q = new DBQuery(inputLine + DBQuery.regexsplit + "connectionname" + DBQuery.regexsplit + connectionname);
DOMSource dmsource = q.returns();
***//StreamResult consoleResult = new StreamResult(System.out); //debug***
StreamResult consoleResult = new StreamResult(pstream);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Thread.sleep(100);
***transformer.transform(dmsource, consoleResult);***
//out.println("println this is a testprogram"); // client receive ok
pstream.flush();
System.out.println(connectionname + ": reply sent.");
if (inputLine == endOfCom){
System.out.println(connectionname + ": is satisfied and terminated communication.");
break;
}
}
pstream.close();
csocket.close();
}catch (IOException e) {
System.out.println(e);
}catch (Exception e) {
System.out.println(e);
}
}
}
And the android client code as below:
public void run() {
if (barcode.length() > 0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
socket.setSoTimeout(10000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write(barcode + ENDL);
if(out.checkError()){
showToUI("PrintWriter had error");
} else {
showToUI("Query sent");
}
int i = 0;
while (true) {
try{
if (**(serverResponse = in.readLine()) != null**) {
if(serverResponse == endOfCom){
Log.i("communicated all data", "bye");
out.write(endOfCom + ENDL);
break;
} else{
}
Log.i("server says", serverResponse);
}
//Log.i("server says", (serverResponse == null? "null" :serverResponse ));
}catch(SocketTimeoutException e){
showToUI(barcode + ": Server did not respond in time");
if (i++ > 2) {
break;
}
}
}
} catch (final UnknownHostException e1) {
showToUI(e1.toString());
} catch (final IOException e1) {
showToUI(e1.toString());
} finally{
try {
socket.close();
} catch (IOException e) {
showToUI(e.toString());
}
}
}else{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Please enter something in barcode", Toast.LENGTH_SHORT).show();
}
});
}
}
I have tested that the xml result returned was ok, if the Stream Result was set to System.out instead of the PrintStream pstream, everything prints perfectly to the console.
However with or without pstream.flush(), client received no response at (serverResponse = in.readLine()) != null.
Also the PrintWriter out which was based on the same Socket socket of pstream successfully gave feedback to the client. When out.println("println this is a testprogram"); was called, the client received log at the Log.i("server says", serverResponse); line OK.
One thing to note is that the reply is usually quite long, can be up to 65536 characters or even more, I do not know if that has any implication, I have tried to create a Buffered reader on the android app larger than the replying xml, it still did not work. The machines are communicating on local network, java server program is running on a different machine from the android emulator.
Any help is appreciated, this had been going on for days and nowhere.
readLine() won't return null until the peer closes the connection. And when it does return null, you need to break out of the loop. And don't compare string s with ==.

Socket output response not reaching client

Hi have a socket client that successfully prints to the output stream. The server retrieves it and tries to return the response string on the output stream. However, the response never reaches the client, despite the fact that I can see the debugging trigger on the readLine() method in the client.
Client side snippet
protected static BufferedReader getClientInputChannel() {
BufferedReader inFromServer = null;
try {
if (clientSocket != null)
clientSocket = new Socket(TPS_HOST, TPS_PORT);
inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return inFromServer;
}
if (query != null && !query.isEmpty()) {
System.out.println("RetrievalSystem: send query: " + query);
outToServer.println(query);
String response = getClientInputChannel().readLine();
System.out.println("RetrievalSystem: response from TPS: " + response);
// Close the output stream.
outToServer.close();
}
Server side.
package com.ds;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class TextProcessingServer extends Thread {
protected final static int DEFAULT_TPS_PORT = 8081;
protected int port;
public TextProcessingServer(int defaultTpsPort) {
setPort(defaultTpsPort);
}
public TextProcessingServer() {
setPort(DEFAULT_TPS_PORT);
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
#Override
public void run() {
init();
}
/**
* single threaded query consumer.
*/
protected void init() {
System.out.println("Initializing TPS Server.");
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
serverSocket = new ServerSocket(getPort());
clientSocket = serverSocket.accept();
// set up the read and write end of the communication socket
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter outToClient =
new PrintWriter(clientSocket.getOutputStream(), true);
// retrieve first line of request and set up for parsing
String requestMessageLine = inFromClient.readLine();
while (requestMessageLine.length() > 0) {
System.out.println("TPS SERVER: Incoming request: " + requestMessageLine);
// Send reply
// THIS REPLY NEVER REACHES THE CLIENT.
outToClient.println(queryInvertedIndex(requestMessageLine));
// Now, listen again for the next incoming request.
requestMessageLine = inFromClient.readLine();
}
System.out.println("left client listening mode.");
} catch (IOException e) {
System.out
.println("Exception caught when trying to listen on port "
+ getPort() + " or listening for a connection");
System.out.println(e.getMessage());
} finally {
try {
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public String queryInvertedIndex(String queryString) {
InvertedIndex invIdx = InvertedIndex.getInstance();
// There could be multiple query strings, thus split.
// Also handle html encoded strings: pigs%20fly
String queryStrings[] = queryString.split("%20|\\s");
StringBuilder resultList = new StringBuilder();
for (String key : queryStrings) {
List<Integer> partialResultList = invIdx.get(key);
for (Integer lineNumber : partialResultList)
resultList.append(lineNumber.toString() + " ");
resultList.replace(resultList.length() - 1, resultList.length(),
", ");
}
// Remove the last comma.
if (resultList.length() > 0)
resultList = new StringBuilder(resultList.substring(0,
resultList.length() - 2));
else
resultList = new StringBuilder("[NO_RESULT]");
return resultList.toString();
}
}
i think you are forgetting to flush the output stream.
outToClient.flush();
try that..
Resolved. It is something that you could not see. I called the server from a static class. Changing the class into a non-static class with no static methods helped.

Categories

Resources