【问题标题】:Java - connection to ServerSocket via browser/URLJava - 通过浏览器/URL 连接到 ServerSocket
【发布时间】:2011-10-07 07:00:07
【问题描述】:

我正在编写一个软件,我受到无法使用套接字连接到使用 ServerSocket 的 java 应用程序的限制。

我想我会尝试使用 URL 连接,因为可以定义要连接的端口

例如:

127.0.0.1:62666

我让我的服务器应用程序监听连接并将输入输出到 jTextArea。通过浏览器连接服务器(127.0.0.1:62666)时,输出:

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

我有另一个应用程序通过 URL 连接连接到 ServerSocket:

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();
    }

它打印出“应该可以工作”的消息仅供参考,但它从不向服务器的 jTextArea 写入任何内容。服务器应用程序的代码如下所示:

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();
    }

注意:通过浏览器连接时会显示文本“Testing123”。

所以我想知道如何以我尝试的方式执行此操作,或者可能读取访问 ServerSocket 的 URL,因此我可以在传递参数(在 URL 中)的同时通过 URL 访问它。

希望这是有道理的:)

谢谢, 迈克。

【问题讨论】:

  • 如果你不被允许使用套接字连接......你意识到每个 TCP 连接,包括 URLConnection,都使用一个套接字,对吧?
  • 服务器收到消息了吗?
  • @ryan:我意识到这一点。很难解释。短篇小说:不允许自己直接实例化 Socket 对象。 @john:不,不是。似乎每当我运行应该连接到它的应用程序时,服务器就会“卡住”。每当我尝试通过浏览器连接到 ServerSocket 之后时,它都会继续尝试连接。
  • 迈克,你有没有找到解决办法?我很想知道你发现了什么或选择做什么。
  • 我从未找到使用 URL 的方法。对于我正在做的事情,目前还不允许我实例化套接字对象,所以我几乎没有足够的能力......感谢您的兴趣:)

标签: java sockets url browser serversocket


【解决方案1】:

有一个很好的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"));
            }
        }
    }
}

从浏览器转到http://127.0.0.1:8080/,您将获得当前日期。

【讨论】:

    【解决方案2】:
    writer.println("Hello");
    

    您没有发送任何换行符。此外,您的“应该有效”跟踪位于错误的位置。应该在flush()之后。

    你也没有阅读回复。

    此外,服务器只会显示 POST ... 或 PUT ...,而不是您发送的行。因此,除非您 (a) 使服务器具有 HTTP 意识或 (b) 摆脱无法使用 Socket 的疯狂限制,否则这永远不会起作用。 为什么你不能使用 Socket?

    编辑:我的代码版本如下:

        static class Server implements Runnable
        {
    
            public void run()
            {
                try
                {
                    ServerSocket serverSock = new ServerSocket(62666);
                    for (;;)
                    {
                        Socket sock = serverSock.accept();
                        System.out.println("From IP: " + sock.getInetAddress());
                        BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                        PrintWriter writer = new PrintWriter(sock.getOutputStream());
                        String line;
                        while ((line = reader.readLine()) != null)
                        {
                            System.out.println("\t:" + line);
                        }
                        writer.println("Testing123");
                        writer.close();
                        reader.close();
                        System.out.println("Server exiting");
                        serverSock.close();
                        break;
                    }
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
        static class Client implements Runnable
        {
    
            public void run()
            {
                try
                {
                    URL url = new URL("http://127.0.0.1:62666");
                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                    connection.setDoOutput(true);
    //              connection.setRequestMethod("POST");
                    connection.connect();
                    PrintWriter writer = new PrintWriter(connection.getOutputStream());
                    writer.println("Hello");
                    writer.flush();
                    System.out.println("flushed");
                    int responseCode = connection.getResponseCode();
                    writer.close();
                    BufferedReader  reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    System.out.println("closed");
                    System.out.println("response code="+responseCode);
                    String  line;
                    while ((line = reader.readLine()) != null)
                        System.out.println("client read "+line);
                    reader.close();
                    System.out.println("Client exiting");
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
        public static void  main(String[] args)
        {
            Thread  t = new Thread(new Server());
            t.setDaemon(true);
            t.start();
            new Client().run();
            System.out.println("Main exiting");
        }
    

    【讨论】:

    • 这也是我的第一个想法,但这不是问题。
    • @Ryan Stewart 这里的 println 存在更大的问题。该服务器不可能显示该数据。
    • 你能解释一下为什么吗?我不知所措。 “你好”去哪儿了?
    • @Ryan Stewart 因为它只读取和打印一行,这是第一个 HTTP 标头。它需要读取和显示,直到 readLine() 返回 null。注意 not 直到 readLine() 返回一个空行:这仅表示标题的结尾。接下来是你的“你好”。
    • 你真的运行过这个程序吗?在问题中发布的表单中,它不输出任何内容,因为它从不发送任何内容。通过一些更改,您可以让它发送和接收完整的 HTTP 请求,但“Hello”永远不会出现在任何地方。
    【解决方案3】:

    我无法弄清楚到底发生了什么。 OutputStream 有一些有趣的地方。添加一个

    ((HttpURLConnection) connection).getResponseCode();
    

    connect() 之后和close() 之前的某个位置,您应该会看到一些不同的东西,如果不是您所期望的。

    也许您不应该尝试将 HTTP 用作 hack,而应该使用完整的 HTTP。像您一样使用来自客户端的 HTTP,并在服务器上设置嵌入式 HTTP 服务器。有几个可供选择,实际上只需要几行即可运行:例如GrizzlySimple FrameworkJetty

    【讨论】:

    • 这输出:POST / HTTP/1.1 From IP: /127.0.0.1 所以,基本上是 POST / HTTP/1.1。 (IP部分是我添加的)。我正在考虑像你说的那样让服务器应用程序完全使用 HTTP,如果这很容易的话。不过,如果这会导致任何地方,我宁愿避免它。
    • @Mike:我还没有发现它可以领导任何地方。如果你把你的 readLine() 放入一个循环中,你最终会打印出一个完整的 HTTP 请求,但是你的“Hello”行神秘地不存在。无论我尝试过什么,似乎您自己写入该 OutputStream 的任何内容都会消失。
    【解决方案4】:

    如果您希望客户端使用 URL 连接向服务器发送消息,我认为这是您需要做的:

    public class Client
    {
        public Client()
        {
            try
            {
                url = new URL("http://127.0.0.1:62666");
                URLConnection urlConnection = url.openConnection();
                PrintWriter writer = new PrintWriter(urlConnection.getOutputStream());
                writer.println("Hello World!");
                writer.flush();
                writer.close();
            }catch(Exception e){e.printStackTrace();}
        }
    }
    

    现在是服务器:

    public class Server implements Runnable
    {
        public Server()
        {
            ServerSocket server = new Server(62666);
            client = server.accept();
            new Thread(this).start();  
        }
    
        public void run()
        {
            try
            {
                String message;
                BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()))
                while((message=reader.readLine())!=null)
                {
                    System.out.println("Message from client: "+message);
                }
            }catch(Exception e)
            {
                System.out.println("Client disconnected");
            }
        }
        Socket client;
    }
    

    【讨论】:

    • 我不明白这应该如何工作:/.. 如果您仔细查看我发布的内容,我正在做的基本上是一样的。看不出有什么大的不同。不过还是谢谢。
    • @Mike Haye 如果仔细观察,你会发现至少有两个主要区别。他省略了 doOutput(true) 但还有另一个。
    • @EJP:我看到的唯一区别是这段代码有几个语法错误,并且由于 doOutput 为假而失败。还是不行。
    • @Ryan Stewart 所以你错过了 print/println 的区别。
    • @EJP:我没有错过。这没什么区别。试试看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多