Java - connection to ServerSocket via browser/URL

18,833

Solution 1

There is one very good example:

public class SimpleHTTPServer {
    public static void main(String args[]) throws IOException {
        ServerSocket server = new ServerSocket(8080);
        while (true) {
            try (Socket socket = server.accept()) {
                Date today = new Date();
                String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
                socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
            }
        }
    }
}

Go to http://127.0.0.1:8080/ from browser and you'll get current date.

Solution 2

I can't figure out exactly what's up. There's something funny about that OutputStream. Add a

((HttpURLConnection) connection).getResponseCode();

somewhere after connect() and before close(), and you should see something different, if not what you expect.

Perhaps instead of trying to use HTTP as a hack, you should just go full HTTP. Use HTTP from the client like you already are, and set up an embedded HTTP server on the server. There are several to choose from out there that literally take just a few lines to get running: Grizzly, Simple Framework, or Jetty, for instance.

Share:
18,833
Mike Haye
Author by

Mike Haye

Updated on June 05, 2022

Comments

  • Mike Haye
    Mike Haye almost 2 years

    I'm writing a piece of software, and I'm under the restriction of not being able to use socket to connect to a java application using a ServerSocket.

    I thought I'd try with an URL connection, since it's possible to define which port to connect to

    e.g:

    127.0.0.1:62666
    

    I have my server app listening for connections and writing the input out to a jTextArea. When connecting to the server (127.0.0.1:62666) through a browser, it outputs:

    GET / HTTP/1.1
    GET /favicon.ico HTTP/1.1
    

    I have another app for connecting to the ServerSocket through an URL connection:

    try{
            URL url = new URL("http://127.0.0.1:62666");
            URLConnection connection = url.openConnection();
            connection.setDoOutput(true);
            connection.connect();
            PrintWriter writer = new PrintWriter(connection.getOutputStream());
            writer.print("Hello");
            System.out.println("should have worked");
            writer.flush();
            writer.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    

    It prints out the "should have worked" message fyi, but it never writes anything to the jTextArea of the server. The code for the server app looks like this:

    try{
    
            ServerSocket serverSock = new ServerSocket(62666);
    
            while(doRun){
                Socket sock = serverSock.accept();
                BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                PrintWriter writer = new PrintWriter(sock.getOutputStream());
    
                InfoReader.gui.writeToTextArea(reader.readLine() + " From IP: " + sock.getInetAddress() + "\n");
                writer.println("Testing123");
    
                writer.close();
    
                reader.close();
    
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    

    Note: when connecting through the browser it displays the text "Testing123".

    So I'm wondering how to do this the way I'm trying or perhaps read the URL that the ServerSocket was accessed through, so I could access it through a URL while passing it arguments (in the URL).

    Hope this makes sense :)

    Thanks, Mike.

  • Mike Haye
    Mike Haye almost 13 years
    I don't see how this should work :/.. Basically the same that I'm doing, if you look carefully at what I posted. Don't see any major differences. Thanks though.
  • user207421
    user207421 almost 13 years
    @Mike Haye if you look carefully you will see at least two major differences. He has omitted doOutput(true) hut there is another.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    @EJP: The only differences I see are that this code has several syntax errors and it fails because doOutput is false. It still doesn't work.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    That was my first thought, too, but it's not the problem.
  • user207421
    user207421 almost 13 years
    @Ryan Stewart so you missed the print/println difference.
  • user207421
    user207421 almost 13 years
    @Ryan Stewart there are bigger problems that the println here. That server cannot possibly display that data.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    @EJP: I didn't miss it. It doesn't make a difference. Try it.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    Can you explain why? I'm at a loss. Where is the "Hello" going?
  • Mike Haye
    Mike Haye almost 13 years
    This outputs: POST / HTTP/1.1 From IP: /127.0.0.1 So, basically POST / HTTP/1.1. (the IP part was added by me). I'm considering making the server application full on HTTP like you say, if it's that easy. I'd rather avoid it though, if this leads anywhere.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    @Mike: I haven't found it to lead anywhere. If you put your readLine() into a loop, you'll end up printing out a full HTTP request, but your "Hello" line is mysteriously absent. No matter what I've tried, it seems like anything you write to that OutputStream yourself just disappears.
  • user207421
    user207421 almost 13 years
    @Ryan Stewart because it only read and printed one line, which was the first HTTP header. It needs to read and display until readLine() returns null. NB not just until readLine() returns an empty line: that only indicates the end of the headers. Your "Hello" is next.
  • user207421
    user207421 almost 13 years
    @Ryan Stewart it is missing from the 'only differences I see' above.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    Have you actually run the program? In the form posted in the question, it doesn't output anything because it never sends anything. With a couple of changes, you can get it to both send and receive a complete HTTP request, but "Hello" never appears anywhere.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    @EJP: Sorry, I should have said "the only differences I see in running this code"
  • gsfd
    gsfd almost 13 years
    Well the reason the server wasnt recieving the message was because the server never called reader.readLine(); there was no way for the server to read the message.
  • user207421
    user207421 almost 13 years
    Yes I have, and with the println() correction and the server reading everything to EOS, the server sees everything down to and including "Hello". However as that isn't an HTTP server, it doesn't return valid HTTP so getResponseCode() stalls at the client. The point of the exercise remains entirely obscure. If you can't use a Socket you have to use a higher-level transport, which makes the Server incorrect.
  • user207421
    user207421 almost 13 years
    @Ran Stewart yes and that's one of several reasons why it will never work. Nothing is actually written by HttpURLConnection until you do some input, either via getResponseCode() or by reading the input stream. But there are much bigger problems than that here.
  • Ryan Stewart
    Ryan Stewart almost 13 years
    Wait, you said that "Hello" showed up? Can you post some code that exhibits that behavior? I've yet to see that work, which is kind of the point of this whole thing.