使用 Java 个套接字的 GET 请求
GET request with Java sockets
我正在编写一个简单的程序来向特定的 url“http://badunetworks.com/about/". The request works if I send it to "http://badunetworks.com”发送获取请求,但我需要将其发送到“关于”页面。
package badunetworks;
import java.io.*;
import java.net.*;
public class GetRequest {
public static void main(String[] args) throws Exception {
GetRequest getReq = new GetRequest();
//Runs SendReq passing in the url and port from the command line
getReq.SendReq("www.badunetworks.com/about/", 80);
}
public void SendReq(String url, int port) throws Exception {
//Instantiate a new socket
Socket s = new Socket("www.badunetworks.com/about/", port);
//Instantiates a new PrintWriter passing in the sockets output stream
PrintWriter wtr = new PrintWriter(s.getOutputStream());
//Prints the request string to the output stream
wtr.println("GET / HTTP/1.1");
wtr.println("Host: www.badunetworks.com");
wtr.println("");
wtr.flush();
//Creates a BufferedReader that contains the server response
BufferedReader bufRead = new BufferedReader(new InputStreamReader(s.getInputStream()));
String outStr;
//Prints each line of the response
while((outStr = bufRead.readLine()) != null){
System.out.println(outStr);
}
//Closes out buffer and writer
bufRead.close();
wtr.close();
}
}
你需要打开 Socket 到 url 而没有路径,例如
Socket("www.badunetworks.com", port);
并在发送命令后 GET /{path} HTTP/1.1 例如
GET /about HTTP/1.1
...其他header...
如果关于页面 link 是 about.html,那么您必须将此行 wtr.println("GET / HTTP/1.1")
更改为 wtr.println("GET /about.html HTTP/1.1").
在套接字创建中删除 /about
wtr.println("GET / HTTP/1.1");
--->此行调用指定主机的主页。
当您对网络服务器进行这样的 low-level 访问时,您应该了解 7 OSI layers. Socket is on layer 5 and HTTP on layer 7. That's also the reason, why java.net.Socket 只接受主机名或 InetAddr,不接受 URL。
要使用套接字,您必须正确实现 HTTP 协议,即
- 创建到 host 和 port 的套接字连接,即
www.badunetworks.com
和 80
- 通过路径和协议版本,即
GET /about/ HTTP/1.1
向包含方法、资源的输出流发送HTTP数据包
- 正确阅读并解释回复(headers 和 body)
但我想知道你为什么要把它弄得这么复杂,有很多方法可以自己实现 low-level http 客户端:
- 好旧的 java.net.URL,尽管它的处理方式已被弃用,但它仍然是读取资源的最简单方法之一,只需调用
openStream()
即可读取它
- Apache HTTP Client是java使用最广泛的http客户端实现之一,比通过URL
读取更容易使用和灵活
- javax.ws.rs 有一个很好的构建器 api 用于创建网络客户端
我正在编写一个简单的程序来向特定的 url“http://badunetworks.com/about/". The request works if I send it to "http://badunetworks.com”发送获取请求,但我需要将其发送到“关于”页面。
package badunetworks;
import java.io.*;
import java.net.*;
public class GetRequest {
public static void main(String[] args) throws Exception {
GetRequest getReq = new GetRequest();
//Runs SendReq passing in the url and port from the command line
getReq.SendReq("www.badunetworks.com/about/", 80);
}
public void SendReq(String url, int port) throws Exception {
//Instantiate a new socket
Socket s = new Socket("www.badunetworks.com/about/", port);
//Instantiates a new PrintWriter passing in the sockets output stream
PrintWriter wtr = new PrintWriter(s.getOutputStream());
//Prints the request string to the output stream
wtr.println("GET / HTTP/1.1");
wtr.println("Host: www.badunetworks.com");
wtr.println("");
wtr.flush();
//Creates a BufferedReader that contains the server response
BufferedReader bufRead = new BufferedReader(new InputStreamReader(s.getInputStream()));
String outStr;
//Prints each line of the response
while((outStr = bufRead.readLine()) != null){
System.out.println(outStr);
}
//Closes out buffer and writer
bufRead.close();
wtr.close();
}
}
你需要打开 Socket 到 url 而没有路径,例如
Socket("www.badunetworks.com", port);
并在发送命令后 GET /{path} HTTP/1.1 例如
GET /about HTTP/1.1
...其他header...
如果关于页面 link 是 about.html,那么您必须将此行 wtr.println("GET / HTTP/1.1")
更改为 wtr.println("GET /about.html HTTP/1.1").
在套接字创建中删除 /about
wtr.println("GET / HTTP/1.1");
--->此行调用指定主机的主页。
当您对网络服务器进行这样的 low-level 访问时,您应该了解 7 OSI layers. Socket is on layer 5 and HTTP on layer 7. That's also the reason, why java.net.Socket 只接受主机名或 InetAddr,不接受 URL。 要使用套接字,您必须正确实现 HTTP 协议,即
- 创建到 host 和 port 的套接字连接,即
www.badunetworks.com
和80
- 通过路径和协议版本,即
GET /about/ HTTP/1.1
向包含方法、资源的输出流发送HTTP数据包
- 正确阅读并解释回复(headers 和 body)
但我想知道你为什么要把它弄得这么复杂,有很多方法可以自己实现 low-level http 客户端:
- 好旧的 java.net.URL,尽管它的处理方式已被弃用,但它仍然是读取资源的最简单方法之一,只需调用
openStream()
即可读取它 - Apache HTTP Client是java使用最广泛的http客户端实现之一,比通过URL 读取更容易使用和灵活
- javax.ws.rs 有一个很好的构建器 api 用于创建网络客户端