将Java应用程序绑定到接口

我有根访问一个GNU / Linux服务器与2个接口。 我正在使用Jericho和HtmlUnit来抓取一些网页。 我想指定哪个接口应该用于HTTP连接。 有没有办法做到这一点在命令行或Java?

我想指定哪个接口应该用于HTTP连接。

每个网络接口都有自己的唯一IP地址。 您通过连接到接口的IP地址上的端口来绑定到接口。

我没有访问套接字。 我给HtmlUnit一个URL。

无论您使用套接字(通过Socket / InetAddress )还是使用HTTP连接(通过URL ),您都使用相同的方法 – 绑定到IP地址+端口。

确定哪个接口有哪个地址

  • 使用Linux命令:

      ip a ip link show /sbin/ifconfig -a lshw -class network 
  • 使用Java( java.net.NetworkInterface类):

      import java.io.*; import java.net.*; import java.util.*; import static java.lang.System.out; public class ListNIFs { public static void main(String args[]) throws SocketException { Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface netIf : Collections.list(nets)) { out.printf("Display name: %s\n", netIf.getDisplayName()); out.printf("Name: %s\n", netIf.getName()); Enumeration<InetAddress> inetAddresses = netIf.getInetAddresses(); for (InetAddress add : Collections.list(inetAddresses)) { out.printf("Address: %s\n", add.getName().getAddress().getHostAddress()); } displaySubInterfaces(netIf); out.printf("\n"); } } static void displaySubInterfaces(NetworkInterface netIf) throws SocketException { Enumeration<NetworkInterface> subIfs = netIf.getSubInterfaces(); for (NetworkInterface subIf : Collections.list(subIfs)) { out.printf("\tSub Interface Display name: %s\n", subIf.getDisplayName()); out.printf("\tSub Interface Name: %s\n", subIf.getName()); Enumeration<InetAddress> inetAddresses = subIf.getInetAddresses(); for (InetAddress add : Collections.list(inetAddresses)) { out.printf("\t Sub Interface Address: %s\n", add.getName().getAddress().getHostAddress()); } } } } 

HTML单位:指定IP地址和端口

如果您正在调用HTMLUnitWebClient ,例如:

 com.gargoylesoftware.htmlunit.WebClient webClient = new WebClient(); com.gargoylesoftware.htmlunit.html.HtmlPage page = webClient.getPage("http://mycompany.org/mypage"); 

那么你可以做任何以下的事情:

 com.gargoylesoftware.htmlunit.html.HtmlPage page = webClient.getPage("http://255.255.255.0:80/mypage"); java.net.URL url = new java.net.URL("http://255.255.255.0:80/mypage"); page = webClient.getPage(url); com.gargoylesoftware.htmlunit.WebRequest req = new com.gargoylesoftware.htmlunit.WebRequest(url, com.gargoylesoftware.htmlunit.HttpMethod.GET); page = webClient.getPage(req); 

您也可以使用HTMLUnit HttpWebConnection

 com.gargoylesoftware.htmlunit.HttpWebConnection conn = new com.gargoylesoftware.htmlunit.HttpWebConnection(webClient); java.net.URL url = new java.net.URL("http://255.255.255.0/mypage"); com.gargoylesoftware.htmlunit.WebRequest req = new com.gargoylesoftware.htmlunit.WebRequest(url, com.gargoylesoftware.htmlunit.HttpMethod.POST); com.gargoylesoftware.htmlunit.WebRequest resp = conn.getResponse(req); 

核心Java:选项指定HTTP连接的URL

创建一个URL来连接资源(文件,网页等)。 您可以使用主机字符串(自动DNS查找)或IP地址指定URL。 您可以选择添加端口:

  // does not encode URL for you (manually include %20, etc) java.net.URL url = new URL("http://255.255.255.20:80/docs/books/tutorial/index.html?name=networking#DOWNLOADING"); java.net.URL url2 = new URL("http", "255.255.255.20", 80, "/docs/books/tutorial/index.html?name=networking#DOWNLOADING"); java.net.URL url3 = new java.net.URL("https://maps.google.com/maps?q=sydney"); java.net.URL url4 = new java.net.URL("https", "maps.google.com", 80, "/maps?q=sydney"); // does encoding of URL string for you java.net.URI uri5 = new URI("http", "example.com", "/hello world/", ""); java.net.URL url5 = uri2.toURL(); // Can then pass URL to HTMLUnit, or invoke yourself // (see Java Network Tutorial for details): java.net.URLConnection conn = url.openConnection(); java.net.HttpConnection httpConn = (HttpConnection)conn; // preconnection: call setAllowUserInteraction/setDoInput/setDoOutput/ // setIfModifiedSince/setUseCaches/setRequestProperty httpConn.connect(); // or getInputStream/getOutputStream/getContent/getHeaderField // postconnection: call getContentEncoding/getContentLength/getContentType // getDate/getExpiration/getLastModifed 

核心Java:选项来指定InetAddress(用于套接字连接)

使用IP地址

  // 4 bytes: byte[] ip4Address = {101,119,11,106}; java.net.InetAddress addressObj = java.net.InetAddress.getByAddress(ip4Address); // or use ip6Address, 16 bytes (2001:0db8:85a3:0000:0000:8a2e:0370:7334): // Any hex value above 0x7f must be cast to byte, because byte is signed (-128 to 127) byte[] ip6Address = {0x20,0x01,0x0d,(byte)0xb8,(byte)0x85,(byte)0xa3,0x00,0x00,0x00,0x00,(byte)0x8a,0x2e,0x03,0x70,0x73,0x34}; 

使用URL字符串(DNS查找)

  java.net.InetAddress addressObj = java.net.InetAddress.getByName("www.google.com"); 

在Java中,您必须将套接字绑定到您要使用的NIC的本地IP地址。 如果你使用的是0.0.0.0,它绑定到ALL。 指定它只使用你想要的。

有两种方式来做到这一点。

  1. 在Java中,关键点是在调用HTTPConnection#open()方法之前指定要使用的源地址:

    InetAddress favourateAddr = InetAddress(byte [] {1,2,3,4}); // 1.2.3.4是您要使用的网卡的IP地址

    yourHTTPConnObj.setLocalAddress(favourateAddr);

    //然后打开http连接yourHTTPConnObj.open();

  2. 在Linux中,第三层使用情况决定了选择NIC的路由。 所以您需要使用目标地址来自定义路由表,以强制您的连接从哪个NIC开始。 这很简单,只有一个路由命令。 看到这个链接 。