Java - 通过浏览器/URL 连接到 ServerSocket
Posted
技术标签:
【中文标题】Java - 通过浏览器/URL 连接到 ServerSocket【英文标题】:Java - connection to ServerSocket via browser/URL 【发布时间】: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 的方法。对于我正在做的事情,目前还不允许我实例化套接字对象,所以我几乎没有足够的能力......感谢您的兴趣:) 【参考方案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 服务器。有几个可供选择,实际上只需要几行即可运行:例如Grizzly、Simple Framework 或Jetty。
【讨论】:
这输出: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:我没有错过。这没什么区别。试试看。以上是关于Java - 通过浏览器/URL 连接到 ServerSocket的主要内容,如果未能解决你的问题,请参考以下文章