JAVA网络编程-HTTP

请求和相应

HTTP1.1响应码表
Keep-Alive
HTTP方法
请求主体
Cookie
CookieManager
CookieStore

请求和相应

HTTP是Web浏览器和Web服务器之间通讯的标准协议.HTTP指定客户端与服务器如何建立连接,客户端如何从服务器请求数据,服务器如何相应请求,以及最后如何关闭连接.HTTP连接使用TCP/IP来传输数据.对于从客户端的每一个请求都有4个步骤:

1 默认情况下,客户端在端口80打开与服务器的一个TCP连接,URL中还可以指定其他端口.

2 客户端向服务器发送消息,请求路径上的资源,这个请求包括一个首部,可选地址还有一个空行,后面是这个请求的数据.

3 服务器向客户端发送响应,相应以响应码开头,后面包含元数据的首部,一个空行以及请求的文档或错误信息.

4 服务端关闭连接.

这四个步骤是HTTP1.0的过程,HTTP/1.1及以后版本中,可以通过一个TCP连接连续发送多个请求和相应.也就是说在步骤2和步骤3之间可以反复多次.另外在HTTP1.1中,请求和相应可以分为多个块发送.

每个请求和相应都有同样的基本格式:一个首部行,一个包含元数据的HTTP首部,一个空行,一个消息体.一般的客户端请求如下所示:

GET /index.html HTTP/1.1

User-Agent: Mozilla/5.0(Macintosh;Intel Mac OS X 10.8;rv:20.0)

Gecko/20120102 Firefox/20.0

Host: en.wikipedia.org

Connection: keep-alive

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip,deflate

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

 

像这样的GET请求不包含消息体,所以请求以一个空行结束.

第一行称为请求行,包括一个方法,资源路径以及HTTP版本.方法指定了所请求的操作.GET方法请求服务器返回资源的一个表示./index.html是从服务器请求的资源路径.HTTP/1.1是协议的版本.

尽管所需的就是GET行,但客户端通常在首部中还包含其他信息,各行采用  keyword:value 的格式.

关键字不区分大小写,值有时区分大小写,有时不区分.关键字和值都是能是ASCLL.如果一个值太长,可以在下一行最前边新增一个空格或制表符,接续上一行.

这个例子中的第一个关键字是User-Agent,这会让服务器知道使用的是什么浏览器,并允许服务器发送为特定浏览器类型而优化的文件.

Host: www.cafeaulait.org指定了服务器的主机.

Accept关键字,它告诉服务器,客户端可以处理哪些数据类型.例如Accept: text/html,text/plain,image/gif,image/jpeg

指出了客户端可以处理4中MIME媒体类型.分别对应HTML文档,纯文本和GIF图片以及jpeg图片.

MIME类型分为两级:类型(type)和子类型(subtype).类型非常概括的展示包含的何种数据:图片,文字还是影像.子类型标识数据的特定类型:GIF图片,JPEG图片,TIFF图片.例如,HTML的内容是text/html,那么类型是text,子类型是html.JPEG图片的内容类型是image/jpeg,类型是image,子类是jpeg.已经定义了8个顶级类型.

text/* 表示人可读的文字.

image/* 表示图片.

model/* 表示3D模型,如VRML文件.

audio/* 表示声音.

video/* 表示视频,可能包括声音.

application/* 表示二进制数据.

message/* 表示协议特定的信封,如email消息和HTTP相应.

multipart/* 表示多个文档和资源的容器.

每个类型分别有很多不同的子类型.

最后,请求以一个空行结束,也就是说,包括两个回车/换行对 \r\n

一旦服务器看到这个空行,它就开始通过同一个连接向客户端发送它的相应。这个相应以一个状态行开始,后面是一个首部,这个首部采用请求首部同样的keyword:value 的格式.语法描述相应,然后是一个空行,最后是所请求的资源。

HTTP/1.1 200 OK

Date: Sun,21 Apr 2013 15:12:46 GMT

Server: Apache

Connection: close

Content-Type: text/html;charset=ISO-8859-1

Content-length: 115

<html><head><title>A sample HTML file</title></head>The rest of the document goes here</body></html>

第一行指示了服务器使用的协议(HTTP/1.1)后面是一个响应码,200 OK是常用的响应码,表示这个请求是成功的。其他首部行分别指出请求的日期(采用服务器的时间帧)服务器软件(Apache),承诺服务器结束发送时会关闭连接,MIME媒体类型传输文档的长度(不包含首部)

HTTP1.1响应码表

不论是哪个版本,响应码从100到199总表示一个提供信息的相应,200-299总指示成功,300-399表示重定向,400-499总是指示一个客户端错误,500-599总表示一个服务的错误。

Keep-Alive

HTTP1.0会为每个请求打开一个新连接。实际上,一个典型Web会话中打开和关闭所话费的时间远远大于实际传输数据的时间,特别是有很多小文档的会话。对于使用SSL或TLS的加密HTTPS连接,这个问题尤其严重,因为建立一个安全socket的握手过程比建立一个常规的socket需要更多的工作。

在HTTP1.1和以后版本中,服务器不必在发送响应后就关闭连接。可以保持连接打开在同一个socket上等待来自客户端的新请求。可以在一个TCP连接上连续发送多个请求和相应。不过服务器相应之后,客户端请求的锁步模式还是一样。

客户端可以在HTTP请求首部中包含一个Connection字段,指定值为Keep-Alive,指定值为Keep-Alive,指示它希望重用一个socket

Connection:Keep-Alive

URL类支持HTTP Keep-Alive,除非显示的关闭这个特性。也就是说,在服务器关闭连接之前,如果再次连接到同一个服务器,就会重用socket。

HTTP方法

与HTTP服务器的通讯遵循一种请求-相应模式;先是一个无状态的请求,后面是一个无状态的响应。每个HTTP的请求包括两个或三个部分:

起始行,包含HTTP方法和要执行这个方法的资源路径。

一个包含key-value字段的首部,可以提供元信息,如认证凭据和请求中首选使用的格式。

一个请求主体,包含资源的一个表示(只针对POST和PUT)

主要有4个HTTP方法,来标识可以完成的操作:GET POST PUT DELETE这4个方法并不是任意的,它们有特定的语义。

GET方法可以获取一个资源的表示,GET没有副作用,如果失败,完全可以重复执行GET,而不是用担心任何问题。另外,GET的输出通常会缓存。

PUT方法将资源上传到一个已知的URL的服务器,这个方法并非没有副作用,不过它有幂等性。也就是说,可以重复这个方法而不用担心它是否失败。如果连续两次把同一个文档放到同一个服务器的同一个位置,与只放一次相比,服务器的状态是一致的。

DELETE方法从一个指定URL删除一个资源。同样的,这个方法也并非没有副作用,但也是幂等性的。如果你不确定一个删除请求是否成功(例如,有可能在你发送这个请求之后但在接收相应之前,socket突然断开)在这种情况下,完全可以再次发送这个请求。将同一个资源两次删除不是错误的。

POST方法是最通用的方法,它也将资源上传到一个已知的URL的服务器,但是没有指定服务器如何处理这个新提供的资源。例如,服务器不一定把资源放到目标的URL上,而是有可能把它转移到另一个不同的URL。或者服务器可能使用这个数据来更新一个或多个不同的资源状态。POST要用于不重复的不安全的操作,如完成一个交易。

由于GET请求在URL中包括了所有必要的信息,所以可以对GET请求添加请求参数。POST,PUT,DELETE请求则不能,这事有意这样设计的。GET请求用于非提交的动作,如浏览一个静态的Web页面。而其他方法尤其是POST,则用于提交某个东西的动作。例如,在购物车里新增一个商品应当发送一个GET请求,因为这个动作没有提交,用户还可以放弃这个购物车。不过下单就应当发送一个POST,因为这个动作完成了一个提交。

在实际中,如今POST在Web上被大量滥用,不完成提交的所有安全操作应当使用GET而不是POST。只有真正提交的操作才应当是使用POST。

之所以有时会错误的选择POST而不是GET,一个原因是表单可能需要大量的输入,在这方面有一个老掉牙的误解,以为浏览器只能处理几百个字节的查询字符串。尽管在20世纪90年代中确实是这样,但如今所有主流浏览器都能很好的应对至少2000个字符的URL,如果有更多的表单需要提交,可能需要支持POST。不过对于非浏览器客户端,安全操作还是倾向于使用GET方法。

请求主体

GET方法获取URL所标识的资源的一个表示。用GET从服务器获取的资源的具体位置由路径和查询字符串的不同部分指定。不同的路径和查询字符串如何映射到不同的资源要由服务器来确定,URL类并不关心这些。只要它直到URL,就能从那里下载。

POST和PUT要更为复杂。在这些情况下,客户端除了要提供路径和查询字符串,还要提供资源的表示。资源表示在请求主体中发送,放在首部后面。也就是说,它会按顺序发送以下4项。

1 一个起始行,包括方法,路径和查询字符串,以及HTTP版本

2 一个HTTP首部

3 一个空行(连续两个回车/换行对)

4 主体

例如,下面这个POST请求向服务器发送表单数据

POST /cgi-bin/register.pl HTTP 1.0

Date: Sun,27 Apr 2013 12:32:36

Host:www.cafeaulait.org

Content-type: application/x-www-form-urlencoded

Content-lenght: 54

在这个例子中,主体包含一个application/x-www-form-urlencoded数据,但并不只有这一个可能,一般来讲,主体可以包含任意的子节。不过,HTTP首部要包括两个字段指定主体的性质

一个Content-lengh字段,指定主体有多少个子节

一个Content-type字段,指定类型的MIME媒体类型

前例中使用的application/x-www-form-urlencoded MIME类型很常见,因为Web浏览器大多数提交表单就采用这种编码方式,因此很多服务器端程序都使用这个MIME类型与浏览器对话。不过,这绝不是主体能发送的唯一类型。例如向一个照片共享网站上传图片的相机可以发送image/jepg。文本编辑器可以发送text/html。最后都是作为子节传送。

例如,下面是一个上传Atom文档的PUT请求

PUT /blog/software-development/the-power-of-pomodores/ HTTP/1.1

Host: elharo.com

User-Agent: AtomMaker/1.0

Authorization: Basic ZGFmZnk6c2VjZXJldA==

Content-Type: application/atom+xml;type=entry

Content-Length: 322

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">

 <title>The Power of Pomodores</title>

 <id>urn:uuid:11111111111111</id>

</entry>

Cookie

很多网站使用一些小文本串在连接之间存储持久的客户端状态,这些小文本串称为cookie。cookie在请求和相应的HTTP首部,从服务器传递到客户端,再从客户端传回到服务器。服务器使用cookie来指示会话ID,购物车内容,登录凭据,用户首选项等。

例如,一个在线书店设置设置cookie可能值为ISBN=JavaONE&price=12.3 指定我从购物车里放入一本书。不过,cookie值更有可能是一个无意义的字符串。如ADFDSFAS,表示某种数据库中特定的记录,实际信息存储在数据库中。cookie值通常不包含数据,只是指定服务器上的记录。

cookie只能是非空白的ASCLL文本,不能包含逗号或者分号。

要在浏览器中设置一个cookie,服务器会在HTTP首部中包含一个Set-Cookie首部行。例如,下面的HTTP首部将cookie ‘cart’的值设置为 ‘ATVPDKIKX0DER’

HTTP/1.1 200 OK

Content-type: text/html

Set-Cookie: cart=ATVPDKIKX0DER

如果浏览器在向同一个服务器做第二个请求,它会在HTTP请求的首部行中的Cookie行发回这个cookie,如下所示

GET /index.html HTTP/1.1

Host: www.example.org

Cookie: cart=ATVPDKIKXoDER

Accpet: text/html

只要服务器部重用cookie,这会使它在多个HTTP连接上跟踪各个用户和会话。

服务器可以设置不止一个cookie。例如,我向Amazon发出的一个请求在我得浏览器上设置了5个cookie

Set-Cookie:skin=noskin

Set-Cookie:ubid-main=176-212121

Set-Cookie:session-token=ffffffffff

Set-Cookie:session-id-time=dddddddddddddddd

Set-Cookie:session-id=2323232

除了简单的name=value,cookie还可以有多个属性来控制它们的作用域,包括过期时间,路径,域,端口,版本和安全选项。

默认情况下,cookie来自哪个服务器就应用于哪个服务器,如果一个cookie由www.foo.example.com设置,浏览器就只把这个cookie发回给www.foo.example.com不过网站也可以指示一个cookie应用于整个子域,而不只是最初的服务器。例如下面请求为整个个foo.example.com域设置一个用户cookie:

Sete-Cookie: user=elharo;Domain=.foo.example.com

Cookie的作用域还受路径限制,所以会返回给服务器上的某些目录,而不是全部。默认作用域是最初的URL和所有子目录。例如如果URL http://www.cafeconleche.org/XOM设置一个cookie,那么这个cookie还可以应用于http://www.cafeconleche.org/XOM/apidocs/ 但不能应用于http://www.cafeconleche.org/slids。不过使用cookie中的Path属性改变默认作用域。例如下面的相应为浏览器发送了一个key为'user'value为'elharo'的cookie,它只应用于服务器的/restricted子树,而不能应用与网站的其他部分。

Set-Cookie: user=elharo; Path=/restricted

请求相同服务器上子树/restricted中的一个文档时,客户端会回显这个cookie。不过,它不会在网站的其他目录中使用这个cookie。

cookie可以同时包括域和路径。例如下面cookie应用于example.com域中的任意服务器的/restricted路径。

Set-Cookie: user=elharo;Path=/restricted;Domain=.example.com

服务器相应中的不同的cookie属性的顺序无关紧要,只要它们全部使用分号隔开。但是客户端把cookie发回给服务器时,路径必须放到前边。如下

Cookie: user=elharo; Path=/restricted;Domain=.foo.example.com。

可以通过设置expires属性设置cookie在某个时间点过期。

Set-Cookie: user=elharo; expires=Wed,21-Dec-2015 14:23:00 GMT

在这个日期过去后,浏览器应当从缓存中删除这个cookie。

Max-Age属性可以设置cookie经过一定的秒数后过期,而不是特定的时刻。

Set-Cookie: user="elharo"; Max-Age=500

因为cookie可能包含了敏感信息,如口令和会话密匙,所以一些cookie事务应当是安全的。大多数情况下,这意味着使用HTTPS代替HTTP不论表示什么,每个cookie都有一个没有值的secure属性如

Set-Cookie: key=1232; Domain=.foo.example.com;secure

浏览器应当拒绝通过非安全通道发送这种cookie

为了针对cookie窃取攻击提高安全性,cookie可以设置HttpOnly属性。这会告诉浏览器只通过HTTP和HTTPS返回cookie,特别强调不能由JavaSeript返回:

Set-Cookie: key=1223;Domain=.foo.example.com;secure;httponly

CookieManager

java5包括了一个抽象类Java.net.CookieHandler,它定义了如何存储和获取cookie的一个API,但不包括这个抽象类的实现。Java6进一步做了补充为CookieHandler增加了一个可以使用的具体子类java.net.CookieManager不过默认情况下cookie并不打开。在Java存储和返回cookie之前,需要先启用cookie。

使用以下代码后在你用URL类连接的HTTP服务器,Java会存储这些服务器发送的cookie。

public static void main(String[] args) {
        CookieManager manager = new CookieManager();
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);//接收所有Cookie
        manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);//拒绝所有cookie
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);//只接收第一方的cookie
        manager.setCookiePolicy(new CookiePolicy() {
            @Override
            public boolean shouldAccept(URI uri, HttpCookie cookie) {
                //自己实现接收cookie的策略
                return false;
            }
            
        });
        CookieHandler.setDefault(manager);
    }

CookieStore

有必要时要在本地存放,获取cookie。例如在一个应用退出时,可以把cookie保存在磁盘上,下次启动时在加载这些cookie。可以使用getCookieStore()方法获取这个cookie库,CookieManager就在这里保持它的cookie。

public static void main(String[] args) throws Exception {
        
        CookieManager manager = new CookieManager();
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);// 接收所有Cookie
        CookieHandler.setDefault(manager);

         try {
                URL u1 = new URL("https://www.cnblogs.com/zumengjie/p/14959200.html");
                try (BufferedReader br = new BufferedReader(new InputStreamReader(u1.openStream()))) {
                    String s = null;
                    while ((s = br.readLine()) != null) {
                        System.out.println(s);
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }

        CookieStore cookieStore = manager.getCookieStore();
        List<HttpCookie> cookies = cookieStore.getCookies();
        System.out.println(cookies.size());
        for(HttpCookie cookie:cookies) {
            String name = cookie.getName();
            String value = cookie.getValue();
            System.out.println(name+"---------"+value);
        }
    }
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="referrer" content="origin-when-crossorigin" />
    <meta name="description" content="IP和DNS 连接到Internet的设备称为节点,计算机节点称为主机.每个节点或主机都由至少一个唯一的数来标识,这称为Internet地址或者IP地址.目前大多数的IP地址是4个字节长,这被称作IP" />
    <meta property="og:description" content="IP和DNS 连接到Internet的设备称为节点,计算机节点称为主机.每个节点或主机都由至少一个唯一的数来标识,这称为Internet地址或者IP地址.目前大多数的IP地址是4个字节长,这被称作IP" />
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>JAVA网络编程-Internet地址 - 顶风少年 - 博客园</title>
    <link id="favicon" rel="shortcut icon" href="//common.cnblogs.com/favicon.svg" type="image/svg+xml" />
    
    <link rel="stylesheet" href="/css/blog-common.min.css?v=bGZJiuIyKyLRg9ACfTE4SDD6GTeKeXbhYt9jytXng9w" />
    <link id="MainCss" rel="stylesheet" href="/skins/chinaheart/bundle-chinaheart.min.css?v=7loUPf9Ai5e8gCuZP4Vt3rmXXlD6NZCaC7AG1hv3LLY" />
    <link type="text/css" rel="stylesheet" href="https://www.cnblogs.com/zumengjie/custom.css?v=OjJmsfRbPYiLXCS6TEfeF/j6kJE=" />
    <link id="mobile-style" media="only screen and (max-width: 767px)" type="text/css" rel="stylesheet" href="/skins/chinaheart/bundle-chinaheart-mobile.min.css?v=twQpMAIgsn1kyr1GI08lxoqwr9DZILwN56KRVmSOmRE" />
    
    <link type="application/rss+xml" rel="alternate" href="https://www.cnblogs.com/zumengjie/rss" />
    <link type="application/rsd+xml" rel="EditURI" href="https://www.cnblogs.com/zumengjie/rsd.xml" />
    <link type="application/wlwmanifest+xml" rel="wlwmanifest" href="https://www.cnblogs.com/zumengjie/wlwmanifest.xml" />
    <script>
        var currentBlogId = 531767;
        var currentBlogApp = 'zumengjie';
        var cb_enable_mathjax = false;
        var isLogined = false;
        var isBlogOwner = false;
        var skinName = 'ChinaHeart';
        var visitorUserId = '';
    </script>
        <script>
            var currentPostDateAdded = '2021-07-01 11:41';
        </script>
    <script src="https://common.cnblogs.com/scripts/jquery-2.2.0.min.js"></script>
    <script src="/js/blog-common.min.js?v=ZUvfwhWs5fv-s8Nv7WofCOhwKAxiDO928zdWFzhnOPk"></script>
    
    
    
</head>
<body class="has-navbar">
    <a name="top"></a>
    <div id="top_nav" class="navbar forpc">
        <nav id="nav_main" class="navbar-main">
            <ul id="nav_left" class="navbar-list navbar-left">
                <li class="navbar-branding"><a href="https://www.cnblogs.com/" title="开发者的网上家园"><img src="/images/logo.svg?v=R9M0WmLAIPVydmdzE2keuvnjl-bPR7_35oHqtiBzGsM" alt="博客园Logo" /></a></li>
                <li><a href="/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-sitehome')">首页</a></li>
                <li><a href="https://news.cnblogs.com/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-news')">新闻</a></li>
                <li><a href="https://q.cnblogs.com/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-q')">博问</a></li>
                <li><a id="nav_brandzone" href="https://brands.cnblogs.com/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-brands')">专区</a></li>
                <li><a href="https://ing.cnblogs.com/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-ing')">闪存</a></li>
                <li><a href="https://edu.cnblogs.com/" onclick="ga('send', 'event', 'Link', 'click', 'skin-navbar-edu')">班级</a></li>
            </ul>
            <ul id="nav_right" class="navbar-list navbar-right">
                <li>
                    <form id="zzk_search" class="navbar-search" action="https://zzk.cnblogs.com/s" method="get">
                        <input name="w" id="zzk_search_input" placeholder="代码改变世界" type="text" tabindex="3" />
                        <button type="submit" id="zzk_search_button">
                            <img src="/images/aggsite/search.svg" alt="搜索" />
                        </button>
                    </form>
                </li>
                <li id="navbar_login_status" class="navbar-list">
                    <a class="navbar-user-info navbar-blog" href="https://i.cnblogs.com/EditPosts.aspx?opt=1" alt="写随笔" title="写随笔">
                        <img id="new_post_icon" class="navbar-icon" src="/images/aggsite/newpost.svg" alt="写随笔" />
                    </a>
                    <a id="navblog-myblog-icon" class="navbar-user-info navbar-blog" href="https://passport.cnblogs.com/GetBlogApplyStatus.aspx" alt="我的博客" title="我的博客">
                        <img id="myblog_icon" class="navbar-icon" src="/images/aggsite/myblog.svg" alt="我的博客" />
                    </a>
                    <a class="navbar-user-info navbar-message navbar-icon-wrapper" href="https://msg.cnblogs.com/" alt="短消息" title="短消息">
                        <img id="msg_icon" class="navbar-icon" src="/images/aggsite/message.svg?v=J0WS2P2iPgaIVgXxcAhliw4AFZIpaTWxtdoNAv9eiCA" alt="短消息" />
                        <span id="msg_count" style="display: none"></span>
                    </a>
                    <div id="user_info" class="navbar-user-info dropdown">
                        <a class="dropdown-button" href="https://home.cnblogs.com/">
                            <img id="user_icon" class="navbar-avatar" src="/images/aggsite/avatar-default.svg" alt="用户头像" />
                        </a>
                        <div class="dropdown-menu">
                            <a id="navblog-myblog-text" href="https://passport.cnblogs.com/GetBlogApplyStatus.aspx">我的博客</a>
                            <a href="https://home.cnblogs.com/">我的园子</a>
                            <a href="https://account.cnblogs.com/settings/account">账号设置</a>
                            <a href="javascript:void(0)" id="navbar_lite_mode_toggle" title="简洁模式会使用简洁款皮肤显示所有博客">
    简洁模式 <img id="navbar_lite_mode_on" src="/images/lite-mode-check.svg" class="hide" /><span id="navbar_lite_mode_spinner" class="hide">...</span>
</a>
                            <a href="javascript:void(0)" onclick="account.logout();">退出登录</a>
                        </div>
                    </div>
                    <a class="navbar-anonymous" href="https://account.cnblogs.com/signup/">注册</a>
                    <a class="navbar-anonymous" href="javascript:void(0);" onclick="account.login()">登录</a>
                </li>
            </ul>
        </nav>
    </div>

    <div id="page_begin_html">
        <span id="top"></span>
    </div>
    
<!--done-->
<div id="home">
<div id="header">
    <div id="blogTitle">
    <a href="https://www.cnblogs.com/zumengjie/"></a>            
        
<!--done-->
<h1><a id="Header1_HeaderTitle" class="headermaintitle HeaderMainTitle" href="https://www.cnblogs.com/zumengjie/">顶风少年的博客</a>
</h1>
<h2></h2>




        
    </div><!--end: blogTitle 博客的标题和副标题 -->
    <div id="navigator">
        
<ul id="navList">
    <li><a id="blog_nav_sitehome" class="menu" href="https://www.cnblogs.com/">
博客园</a>
</li>
    <li><a href="https://home.cnblogs.com/">园子</a></li>
    <li>
<a id="blog_nav_myhome" class="menu" href="https://www.cnblogs.com/zumengjie/">
首页</a>
</li>
    <li>

<a id="blog_nav_newpost" class="menu" href="https://i.cnblogs.com/EditPosts.aspx?opt=1">
新随笔</a>
</li>
    <li>
<a id="blog_nav_contact" class="menu" href="https://msg.cnblogs.com/send/%E9%A1%B6%E9%A3%8E%E5%B0%91%E5%B9%B4">
联系</a></li>
    <li>
<a id="blog_nav_admin" class="menu" href="https://i.cnblogs.com/">
管理</a>
</li>
    <li>
<a id="blog_nav_rss" class="menu" href="javascript:void(0)" data-rss="https://www.cnblogs.com/zumengjie/rss/">
订阅</a>
    
<a id="blog_nav_rss_image" href="https://www.cnblogs.com/zumengjie/rss/">
    <img src="/skins/chinaheart/images/xml.gif" alt="订阅" />
</a></li>
</ul>



        <div class="clear"></div>
        <div class="blogStats">
            
            <div id="blog_stats_place_holder"><script>loadBlogStats();</script></div>            
                        
        </div><!--end: blogStats -->
    </div><!--end: navigator 博客导航栏 -->
</div><!--end: header 头部 -->

<div id="main">
    <div id="topicList">
    <div class="forFlow">
        <div id="post_detail">
<!--done-->
<div id="topics">
    <div class="post">
        <h1 class = "postTitle">
            
<a id="cb_post_title_url" class="postTitle2 vertical-middle" href="https://www.cnblogs.com/zumengjie/p/14959200.html">
    <span>JAVA网络编程-Internet地址</span>
    



</a>

        </h1>
        <div class="clear"></div>
        <div class="postBody">
            <div id="cnblogs_post_body" class="blogpost-body blogpost-body-html">
<h1><span style="font-family: 宋体">IP和DNS</span></h1>
<p><span style="font-family: 宋体">连接到Internet的设备称为节点,计算机节点称为主机.每个节点或主机都由至少一个唯一的数来标识,这称为Internet地址或者IP地址.目前大多数的IP地址是4个字节长,这被称作IPv4地址.不过,一小部分IP地址是16字节长,这被称作IPv6地址.IP地址对于人们来说是很难记忆的数字,为了避免到处携带记满IP地址的通讯录,Internet的设计者发明了域名系统(Domain Name System DNS).DNS将人们可以记忆的主机名与计算机可以记住的IP地址关联在一起。服务器通常至少有一个主机名。客户端往往有一个主机名,但也可能没有,特别是有些客户端的IP地址会在启动时动态指定。</span></p>
<p><span style="font-family: 宋体"><span style="background-color: rgba(0, 255, 0, 1)">有些IP有多个DNS,多个域名对应一个IP地址。也有一个域名映射多个IP地址的情况,这时就要由DNS服务器负责随机选择一台机器来相应各个请求。每台连接到Internet的计算机都能访问到一个称为域名服务器的机器,它通常时一个运行特殊DNS软件的UNIX主机,这种软件了解不同主机名和IP地址之间的映射。</span>大多数域名服务器只直到其本地网络上主机的地址,以及其他网站中一些域名服务器地址。如果客户端请求本地域名之外一个机器的地址,本地域名服务器就会询问远程位置的域名服务器,在将答案转发给请求者。</span></p>
<p><span style="font-family: 宋体">大多数情况下,可以使用主机名而让DNS处理向IP地址的转换。只要能连接到一个域名服务器,就不需要担心你的机器,本地域名服务器和Internet其他部分之间传递主机名和地址的有关细节。前提是你的机器必须连接到Internet.</span></p>
<h1><span style="font-family: 宋体">InetAddress对象</span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {<span style="background-color: rgba(0, 255, 0, 1)">//通过域名获取IP</span>
        InetAddress i </span>= InetAddress.getByName("www.oreilly.com"<span style="color: rgba(0, 0, 0, 1)">);
        System.out.println(</span>"~~~  " +<span style="color: rgba(0, 0, 0, 1)"> i.getHostAddress());//104.86.0.99
        System.out.println(</span>"~~~  " +<span style="color: rgba(0, 0, 0, 1)"> i.getHostName());//www.oreilly.com
    }</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Test {<span style="background-color: rgba(0, 255, 0, 1)">//通过域名获取所有地址</span>
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {
        InetAddress[] is </span>= InetAddress.getAllByName("www.baidu.com"<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(InetAddress address: is) {
            System.out.println(</span>"~~~  " +<span style="color: rgba(0, 0, 0, 1)"> address.getHostAddress());
            System.out.println(</span>"~~~  " +<span style="color: rgba(0, 0, 0, 1)"> address.getHostName());
        }
    }
}<br></span></pre>
<p>~~~ 110.242.68.3<br>~~~  www.baidu.com<br>~~~  110.242.68.4<br>~~~  www.baidu.com</p>

</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {<span style="background-color: rgba(0, 255, 0, 1)">//获取本机的主机名和IP地址</span>
        InetAddress me </span>=<span style="color: rgba(0, 0, 0, 1)"> InetAddress.getLocalHost();
        System.out.println(me.getHostName());</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">DESKTOP-MLQ0UUB</span>
        System.out.println(me.getHostAddress());<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">169.254.49.55</span>
    }</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {<span style="background-color: rgba(0, 255, 0, 1)">//测试主机是否可达</span>
        InetAddress me </span>= InetAddress.getByName("www.baidu.com"<span style="color: rgba(0, 0, 0, 1)">);
        System.out.println(me.isReachable(</span>1000<span style="color: rgba(0, 0, 0, 1)">));
}</span></pre>
</div>
<p>&nbsp;</p>
</div>
<div class="clear"></div>
<div id="blog_post_info_block">
    <div id="blog_post_info"></div>
    <div class="clear"></div>
    <div id="post_next_prev"></div>
</div>
        </div>
        <div class="postDesc">posted @ 
<span id="post-date">2021-07-01 23:41</span>&nbsp;
<a href="https://www.cnblogs.com/zumengjie/">顶风少年</a>&nbsp;
阅读(<span id="post_view_count">5</span>)&nbsp;
评论(<span id="post_comment_count">0</span>)&nbsp;
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=14959200" rel="nofollow">编辑</a>&nbsp;
<a href="javascript:void(0)" onclick="AddToWz(14959200);return false;">收藏</a>&nbsp;
<a href="javascript:void(0)" onclick="reportManager.report({ currentUserId: '', targetType: 'blogPost', targetId: '14959200', targetLink: 'https://www.cnblogs.com/zumengjie/p/14959200.html', title: 'JAVA网络编程-Internet地址' })">举报</a></div>
    </div>
    
    
</div><!--end: topics 文章、评论容器-->
<script src="https://common.cnblogs.com/highlight/10.3.1/highlight.min.js"></script>
<script>markdown_highlight();</script>
<script>
    var allowComments = true, cb_blogId = 531767, cb_blogApp = 'zumengjie', cb_blogUserGuid = 'd92ec9f8-28c3-4ec8-c9ec-08d717f6ba49';
    var cb_entryId = 14959200, cb_entryCreatedDate = '2021-07-01 23:41', cb_postType = 1;
    updatePostStats(
        [cb_entryId],
        function(id, count) { $("#post_view_count").text(count) },
        function(id, count) { $("#post_comment_count").text(count) })
    zoomManager.apply("#cnblogs_post_body img:not(.code_img_closed):not(.code_img_opened)");
</script>
<a name="!comments"></a>
<div id="blog-comments-placeholder"></div>
<div id="comment_form" class="commentform">
    <a name="commentform"></a>
    <div id="divCommentShow"></div>
    <div id="comment_nav"><span id="span_refresh_tips"></span><a href="javascript:void(0);" onclick="return RefreshCommentList();" id="lnk_RefreshComments" runat="server" clientidmode="Static">刷新评论</a><a href="#" onclick="return RefreshPage();">刷新页面</a><a href="#top">返回顶部</a></div>
    <div id="comment_form_container"></div>
    <div class="ad_text_commentbox" id="ad_text_under_commentbox"></div>
    <div id="ad_t2"></div>
    <div id="opt_under_post"></div>
    <div id="cnblogs_c1" class="under-post-card">
        <div id='div-gpt-ad-1592365906576-0' style='width: 300px; height: 250px;'></div>
    </div>
    <div id="under_post_card1"></div>
    <div id="cnblogs_c2" class="under-post-card">
        <div id='div-gpt-ad-1592366332455-0' style='width: 468px; height: 60px;'></div>
    </div>
    <div id="under_post_card2"></div>
    <div id="HistoryToday" class="under-post-card"></div>
    <script type="text/javascript">
       var commentManager = new blogCommentManager();
       commentManager.renderComments(0);
       fixPostBody();
       deliverBigBanner();
setTimeout(function() { incrementViewCount(cb_entryId); }, 50);       deliverT2();
       deliverC1C2();
       loadNewsAndKb();
LoadPostCategoriesTags(cb_blogId, cb_entryId);       LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
       GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
       loadOptUnderPost();
       GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);
    </script>
</div>

</div>


    </div><!--end: forFlow -->
    </div><!--end: topicList 文章列表容器-->

    <div id="sideBar">
        <div id="sideBarMain">
            <div id="sidebar_news" class="newsItem">
            <script>loadBlogNews();</script>
</div>
<div id="sidebar_c3"></div>
            <div id="calendar"><div id="blog-calendar" style="display:none"></div><script>loadBlogDefaultCalendar();</script></div>
            
            <DIV id="leftcontentcontainer">
                <div id="blog-sidecolumn"></div>
                    <script>loadBlogSideColumn();</script>
            </DIV>
            
        </div><!--end: sideBarMain -->
    </div><!--end: sideBar 侧边栏容器 -->
    <div class="clear"></div>
    </div><!--end: main -->
    <div class="clear"></div>
    <div id="footer">
    </div><!--end: footer -->
</div><!--end: home 自定义的最大容器 -->


    <div id="page_end_html">
        <span id="back-to-top"><a href="#top">返回顶部</a></span>
    </div>

    <input type="hidden" id="antiforgery_token" value="CfDJ8NACB8VE9qlHm6Ujjqxvg5BzJ1aTZAwA88eEv4Ec88RO8Jm_VNSuyfDV8pNjdi4_GkJTFmd4q7PJVPo-AvoCXwcFH3YnmA_ehDo4pijn8K2xZz3SsjcZgvkMZRCE0kbfxQJzlctu0lvXJLwilU1mJyI" />
</body>
</html>
1
.AspNetCore.Antiforgery.b8-pDmTq1XM---------CfDJ8NACB8VE9qlHm6Ujjqxvg5DTUmxiYuZfVh0j7uncRAP_3IKdtn7xHILb-CDu2iKtx4BrfVNO4mMRQZbouVSI8jSRbyK9zeNOLU4odrdrqGV7ErvlTXvvzeWGllq2QpKUF94HIRFaanc9R4_R-mFb5O8

 

 

 

 

 

 

 

posted @ 2021-07-11 23:43  顶风少年  阅读(100)  评论(0编辑  收藏  举报
返回顶部