精华内容
下载资源
问答
  • 获取最新版本的Chrome的,以使其成为网络请求中的浏览器 某些站点和服务会阻止非浏览器请求或做出不同响应。 我将不时地使用最新的用户代理更新此模块。 安装 $ npm install ua-string 用法 import got from 'got'...
  • 网络请求可能是每门语言比较重要的一部分了,在Python语言中,虽然有urllib这样的自带原生网络请求库,但是它的一些API对待开发者好像不怎么友好。So,Requests的革命开始了,不仅API人性化,更重要的是它支持urllib...

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 极客导航 即可关注,每个工作日都有文章更新。

    一、概况

    网络请求可能是每门语言比较重要的一部分了,在Python语言中,虽然有urllib这样的自带原生网络请求库,但是它的一些API对待开发者好像不怎么友好。So,Requests的革命开始了,不仅API人性化,更重要的是它支持urllib所有特性。

    Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的URLPOST数据自动编码。好处不多说了,我们快来体验一下吧。

    好像忘记说了一句,Requests的库再牛逼,底层也是urllib
    革命

    二、准备

    • 安装requests库
    pip3 install requests
    

    三、使用

    1、Get请求:
    response = requests.get("http://www.baidu.com/")
    

    看到没,对,你没看错,发起GET请求就短短的一行代码。
    返回的response有很多属性,我们来看看:

    response.text  返回解码后的字符串,
    respones.content  以字节形式(二进制)返回。
    response.status_code  响应状态码
    response.request.headers  请求的请求头
    response.headers  响应头
    response.encoding = 'utf-8'   可以设置编码类型
    response.encoding   获取当前的编码
    response.json()  内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常
    
    • 添加参数和请求头
    import requests
    
    #参数
    kw = {'wd':'美女'}
    
    #请求头
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
    }
    
    # params 接收一个字典或者字符串的查询参数,
    # 字典类型自动转换为url编码,不需要urlencode()
    response = requests.get(
        "http://www.baidu.com/s?",
        params = kw, 
        headers = headers
    )
    
    # 查看响应内容,response.text 返回的是Unicode格式的数据
    print (response.text)
    
    # 查看响应内容,response.content返回的字节流数据
    print (respones.content)
    
    # 查看完整url地址
    print (response.url)
    
    # 查看响应头部字符编码
    print (response.encoding)
    
    # 查看响应码
    print (response.status_code)
    

    返回的内容如下:

    ......内容太多,不宜展示
    
    ......内容太多,不宜展示
    
    'http://www.baidu.com/s?wd=%E9%95%BF%E5%9F%8E'
    
    'utf-8'
    
    200
    

    注意

    • 使用response.text时,Requests会基于 HTTP 响应的文本编码自动解码响应内容,大多数 Unicode 字符集都能被无缝地解码。
    • 使用response.content时,返回的是服务器响应数据的原始二进制字节流,可以用来保存图片等二进制文件。

    比如:

    import  requests
    response = requests.get("http://www.sina.com")
    print(response.request.headers)
    print(response.content.decode('utf-8'))
    

    结果:

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <title>新浪首页</title>
        <meta name="keywords" content="新浪,新浪网,SINA,sina,sina.com.cn,新浪首页,门户,资讯" />
        ...
    

    如果用response.text可能会出现乱码情况,比如:

    import requests
    response = requests.get("http://www.sina.com")
    print(response.text)
    

    结果:

    <!DOCTYPE html>
    <!-- [ published at 2017-06-09 15:18:10 ] -->
    <html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <title>新浪首页</title>
        <meta name="keywords" content="新浪,新浪网,SINA,sina,sina.com.cn,新浪首页,门户,资讯" />
        <meta name="description" content="新浪网为全球用户24小时提供全面及时的中文资讯,内容覆盖国内外突发新闻事件、体坛赛事、娱乐时尚、产业资讯、实用信息等,设有新闻、体育、娱乐、财经、科技、房产、汽车等30多个内容频道,同时开设博客、视频、论坛等自由互动交流空间。" />
        <link rel="mask-icon" sizes="any" href="//www.sina.com.cn/favicon.svg" color="red">
    
    • 原因

    当收到一个响应时,Requests会猜测响应的编码方式,用于在你调用response.text方法时对响应进行解码。Requests首先在 HTTP 头部检测是否存在指定的编码方式,如果不存在,则会使用 chardet.detect来尝试猜测编码方式(存在误差),所以更推荐 response.content.deocde()

    2、Post请求:

    网站登录和注册等功能一般都是通过post请求方式做的,学会用Requests发起post请求也是爬取需要登录网站的第一步。

    import requests
    
    #测试请求地址
    req_url = "https://httpbin.org/post"
    
    #表单数据
    formdata = {
        'username': 'test',
        'password': '123456',
    }
    
    #添加请求头
    req_header = {
        'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
    }
    #发起请求
    response = requests.post(
        req_url, 
        data = formdata, 
        headers = req_header
    )
    
    print (response.text)
    # 如果是json文件可以直接显示
    #print (response.json())
    

    结果:

    {
      "args": {},
      "data": "",
      "files": {},
      "form": {
        "password": "123456",
        "username": "test"
      },
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "29",
        "Content-Type": "application/x-www-form-urlencoded",
        "Host": "httpbin.org",
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
      },
      "json": null,
      "origin": "223.72.76.90, 223.72.76.90",
      "url": "https://httpbin.org/post"
    }
    
    • 上传文件
    url = 'https://httpbin.org/post'
    files = {'file': open('image.png', 'rb')}
    response = requests.post(url, files=files)
    print(response.text)
    

    结果:

    {
      "args": {},
      "data": "",
      "files": {
        "file": "....内容太多,不宜展示"
      },
      "form": {},
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "27597",
        "Content-Type": "multipart/form-data; boundary=16afeeccbaec949570677ca271dc2d0c",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.21.0"
      },
      "json": null,
      "origin": "223.72.76.90, 223.72.76.90",
      "url": "https://httpbin.org/post"
    }
    

    四、总结

    以上是Requests最基本的Get请求和Post请求,语法比较简单,这也是学会爬虫的第一步。加油吧!骚年。

    欢迎关注我的公众号,我们一起学习。
    欢迎关注我的公众号

    展开全文
  • Android网络请求

    千次阅读 2018-03-12 17:28:08
    1,Android网络编程系列链接:http://liuwangshu.cn/application/network/1-http.html1.HTTP简介HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式...简单快速:客户向服务器请求服务时...

    1,Android网络编程系列

    链接:http://liuwangshu.cn/application/network/1-http.html

    1.HTTP简介

    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。

    HTTP协议的主要特点

    1. 支持C/S(客户/服务器)模式。
    2. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
    3. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
    4. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
    5. 无状态:HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

    HTTP URL 的格式如下

    http://host[":"port][abs_path]

    http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用默认端口80;abs_path指定请求资源的URI(Web上任意的可用资源)。HTTP有两种报文分别是请求报文和响应报文,让我们先来看看请求报文。

    2.HTTP的请求报文

    先来看看请求报文的一般格式:

    这里写图片描述

    通常来说一个HTTP请求报文由请求行、请求报头、空行、和请求数据4个部分组成。

    请求行

    请求行由请求方法,URL字段和HTTP协议的版本组成,格式如下:

    Method Request-URI HTTP-Version CRLF

    其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。

    HTTP请求方法有8种,分别是GET、POST、DELETE、PUT、HEAD、TRACE、CONNECT 、OPTIONS。其中PUT、DELETE、POST、GET分别对应着增删改查,对于移动开发最常用的就是POST和GET了。

    1. GET:请求获取Request-URI所标识的资源
    2. POST:在Request-URI所标识的资源后附加新的数据
    3. HEAD:请求获取由Request-URI所标识的资源的响应消息报头
    4. PUT: 请求服务器存储一个资源,并用Request-URI作为其标识
    5. DELETE :请求服务器删除Request-URI所标识的资源
    6. TRACE : 请求服务器回送收到的请求信息,主要用于测试或诊断
    7. CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
    8. OPTIONS :请求查询服务器的性能,或者查询与资源相关的选项和需求

    例如我去访问我的CSDN博客地址请求行是:

    GET http://blog.csdn.net/itachi85 HTTP/1.1

    请求报头

    在请求行之后会有0个或者多个请求报头,每个请求报头都包含一个名字和一个值,它们之间用“:”分割。请求头部会以一个空行,发送回车符和换行符,通知服务器以下不会有请求头。关于请求报头,会在后面的消息报头一节做统一的解释。

    请求数据

    请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合,与请求数据相关的最常用的请求头是Content-Type和Content-Length。

    3.HTTP的响应报文

    先来看看响应报文的一般格式:这里写图片描述

    HTTP的响应报文由状态行、消息报头、空行、响应正文组成。响应报头后面会讲到,响应正文是服务器返回的资源的内容,先来看看状态行。

    状态行

    1、状态行格式如下:

    HTTP-Version Status-Code Reason-Phrase CRLF

    其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
    状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

    • 100~199:指示信息,表示请求已接收,继续处理
    • 200~299:请求成功,表示请求已被成功接收、理解、接受
    • 300~399:重定向,要完成请求必须进行更进一步的操作
    • 400~499:客户端错误,请求有语法错误或请求无法实现
    • 500~599:服务器端错误,服务器未能实现合法的请求

    常见的状态码如下:

    • 200 OK:客户端请求成功
    • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
    • 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
    • 403 Forbidden:服务器收到请求,但是拒绝提供服务
    • 500 Internal Server Error:服务器发生不可预期的错误
    • 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常

    例如访问我的CSDN博客地址响应的状态行是:

    HTTP/1.1 200 OK

    4.HTTP的消息报头

    消息报头分为通用报头、请求报头、响应报头、实体报头等。消息头由键值对组成,每行一对,关键字和值用英文冒号“:”分隔。

    通用报头

    既可以出现在请求报头,也可以出现在响应报头中

    • Date:表示消息产生的日期和时间
    • Connection:允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
    • Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)

    请求报头

    请求报头通知服务器关于客户端求求的信息,典型的请求头有:

    • Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
    • User-Agent:发送请求的浏览器类型、操作系统等信息
    • Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
    • Accept-Encoding:客户端可识别的数据编码
    • Accept-Language:表示浏览器所支持的语言类型
    • Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
    • Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。

    响应报头

    用于服务器传递自身信息的响应,常见的响应报头:

    • Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
    • Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的

    实体报头

    实体报头用来定于被传送资源的信息,既可以用于请求也可用于响应。请求和响应消息都可以传送一个实体,常见的实体报头为:

    • Content-Type:发送给接收者的实体正文的媒体类型
    • Content-Lenght:实体正文的长度
    • Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
    • Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
    • Last-Modified:实体报头用于指示资源的最后修改日期和时间
    • Expires:实体报头给出响应过期的日期和时间

    5.应用举例

    要想查看网页或者手机请求网络的请求报文和响应报文有很多种方法,这里推荐采用Fiddler,在Android利用Fiddler进行网络数据抓包这篇文章中详尽介绍了如何使用Fiddler,在这里就不赘述了。打开Fiddler,然后用浏览器访问我的CSDN博客网站:这里写图片描述点击红色画笔的区域就可以看到请求报文和响应报文了

    请求报文:

    GET http://blog.csdn.net/itachi85 HTTP/1.1 //请求行
    Host: blog.csdn.net //请求报头
    Connection: keep-alive
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 QQBrowser/9.3.6872.400
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: zh-CN,zh;q=0.8
    Cookie: bdshare_firstime=1443768140949; uuid_tt_dd=5028529250430960147_20151002;
    ...省略

    很容易看出访问的是我的博客地址http://blog.csdn.net/itachi85,请求的方法是GET,因为是GET方法所以并没有请求数据。

    响应报文:

    HTTP/1.1 200 OK //状态行
    Server: openresty //响应报头
    Date: Sun, 27 Mar 2016 08:26:54 GMT
    Content-Type: text/html; charset=utf-8
    Transfer-Encoding: chunked
    Connection: keep-alive
    Keep-Alive: timeout=20
    Vary: Accept-Encoding
    Cache-Control: private
    X-Powered-By: PHP 5.4.28
    Content-Encoding: gzip
    //不能省略的空格
    28b5
    }ysI 1ߡFsgl n- ]{^_ { 'z! C , m# 0 !l ` 4x ly .ݪ*
    ڴzAt_Xl * 9'O ɬ ' ק 3 ^1a
    ...省略

    响应报文没什么可说的,接下来我们配置好手机网络代理,访问一个应用的界面

    请求报文:

    POST http://patientapi.shoujikanbing.com/api/common/getVersion HTTP/1.1 //请求行
    Content-Length: 226 //请求报头
    Content-Type: application/x-www-form-urlencoded
    Host: patientapi.shoujikanbing.com
    Connection: Keep-Alive
    User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; MI NOTE LTE Build/KTU84P) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
    Accept-Encoding: gzip
    //不能省略的空格,下面是请求数据
    clientversion=2_2.0.0&time=1459069342&appId=android&channel=hjwang&sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9&token=b191944d680145b5ed97f2f4ccf03058&deviceId=869436020220717&type=2&version=2.0.0

    从请求报文的请求行来看,请求的方法是POST,请求地址为http://patientapi.shoujikanbing.com/api/common/getVersion,很显然是获取版本信息的接口。

    响应报文:

    HTTP/1.1 200 OK //状态行
    Server: nginx //响应报头
    Date: Sun, 27 Mar 2016 09:02:20 GMT
    Content-Type: text/html;charset=utf-8
    Transfer-Encoding: chunked
    Connection: keep-alive
    Vary: Accept-Encoding
    Set-Cookie: sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; expires=Mon, 28-Mar-2016 09:02:20 GMT; Max-Age=86400; path=/; domain=.shoujikanbing.com
    Set-Cookie: PHPSESSID=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; path=/; domain=.shoujikanbing.com
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Content-Encoding: gzip
    //不能省略的空格
    17f //实体报文编码格式为gzip所以显示在这里的响应数据是乱码
    mP N @ "E ? n m 1
    w ( HL (1^ P nK E ѷ93'3gNLH 7P $c \ T 4a6 L:+ 1dY%$g h H +
    ...省略

    响应报文的实体采用的编码格式为为gzip,所以在Fiddler软件中显示的是乱码。

    上一篇我们了解了HTTP协议原理,这一篇我们来讲讲Apache的HttpClient和Java的HttpURLConnection,这两种都是我们平常请求网络会用到的。无论我们是自己封装的网络请求类还是第三方的网络请求框架都离不开这两个类库。

    1.HttpClient

    Android SDK中包含了HttpClient,在Android6.0版本直接删除了HttpClient类库,如果仍想使用则解决方法是:

    • 如果使用的是eclipse则在libs中加入org.apache.http.legacy.jar这个jar包在:**sdk\platforms\android-23\optional目录中(需要下载android6.0的SDK)
    • 如果使用的是android studio则 在相应的module下的build.gradle中加入:
    android {
    useLibrary 'org.apache.http.legacy'
    }

    HttpClient的GET请求

    首先我们来用DefaultHttpClient类来实例化一个HttpClient,并配置好默认的请求参数:

    //创建HttpClient
    private HttpClient createHttpClient() {
    HttpParams mDefaultHttpParams = new BasicHttpParams();
    //设置连接超时
    HttpConnectionParams.setConnectionTimeout(mDefaultHttpParams, 15000);
    //设置请求超时
    HttpConnectionParams.setSoTimeout(mDefaultHttpParams, 15000);
    HttpConnectionParams.setTcpNoDelay(mDefaultHttpParams, true);
    HttpProtocolParams.setVersion(mDefaultHttpParams, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(mDefaultHttpParams, HTTP.UTF_8);
    //持续握手
    HttpProtocolParams.setUseExpectContinue(mDefaultHttpParams, true);
    HttpClient mHttpClient = new DefaultHttpClient(mDefaultHttpParams);
    return mHttpClient;
    }

    接下来创建HttpGet和HttpClient,请求网络并得到HttpResponse,并对HttpResponse进行处理:

    private void useHttpClientGet(String url) {
    HttpGet mHttpGet = new HttpGet(url);
    mHttpGet.addHeader("Connection", "Keep-Alive");
    try {
    HttpClient mHttpClient = createHttpClient();
    HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
    HttpEntity mHttpEntity = mHttpResponse.getEntity();
    int code = mHttpResponse.getStatusLine().getStatusCode();
    if (null != mHttpEntity) {
    InputStream mInputStream = mHttpEntity.getContent();
    String respose = converStreamToString(mInputStream);
    Log.i("wangshu", "请求状态码:" + code + "\n请求结果:\n" + respose);
    mInputStream.close();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    converStreamToString方法将请求结果转换成String类型:

    private String converStreamToString(InputStream is) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuffer sb = new StringBuffer();
    String line = null;
    while ((line = reader.readLine()) != null) {
    sb.append(line + "\n");
    }
    String respose = sb.toString();
    return respose;
    }

    最后我们开启线程访问百度:

    new Thread(new Runnable() {
    @Override
    public void run() {
    useHttpClientGet("http://www.baidu.com");
    }
    }).start();

    请求的返回结果,请求状态码为200,结果就是个html页,这里只截取了部分html代码:
    这里写图片描述

    GET请求的参数暴露在URL中,这有些不大妥当,而且URL的长度也有限制:长度在2048字符之内,在HTTP 1.1后URL长度才没有限制。一般情况下POST可以替代GET,接下来我们来看看HttpClient的POST请求。

    HttpClient的POST请求

    post请求和get类似就是需要配置要传递的参数:

    private void useHttpClientPost(String url) {
    HttpPost mHttpPost = new HttpPost(url);
    mHttpPost.addHeader("Connection", "Keep-Alive");
    try {
    HttpClient mHttpClient = createHttpClient();
    List<NameValuePair> postParams = new ArrayList<>();
    //要传递的参数
    postParams.add(new BasicNameValuePair("username", "moon"));
    postParams.add(new BasicNameValuePair("password", "123"));
    mHttpPost.setEntity(new UrlEncodedFormEntity(postParams));
    HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
    HttpEntity mHttpEntity = mHttpResponse.getEntity();
    int code = mHttpResponse.getStatusLine().getStatusCode();
    if (null != mHttpEntity) {
    InputStream mInputStream = mHttpEntity.getContent();
    String respose = converStreamToString(mInputStream);
    Log.i("wangshu", "请求状态码:" + code + "\n请求结果:\n" + respose);
    mInputStream.close();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    2.HttpURLConnection

    Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:

    private void disableConnectionReuseIfNecessary() {
    // 这是一个2.2版本之前的bug
    if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
    System.setProperty("http.keepAlive", "false");
    }
    }

    所以在Android 2.2版本以及之前的版本使用HttpClient是较好的选择,而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择,它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。另外在Android 6.0版本中,HttpClient库被移除了,HttpURLConnection则是以后我们唯一的选择。

    HttpURLConnection的POST请求

    因为会了HttpURLConnection的POST请求那GET请求也就会了,所以我这里只举出POST的例子
    首先我们创建一个UrlConnManager类,然后里面提供getHttpURLConnection()方法用于配置默认的参数并返回HttpURLConnection:

    public static HttpURLConnection getHttpURLConnection(String url){
    HttpURLConnection mHttpURLConnection=null;
    try {
    URL mUrl=new URL(url);
    mHttpURLConnection=(HttpURLConnection)mUrl.openConnection();
    //设置链接超时时间
    mHttpURLConnection.setConnectTimeout(15000);
    //设置读取超时时间
    mHttpURLConnection.setReadTimeout(15000);
    //设置请求参数
    mHttpURLConnection.setRequestMethod("POST");
    //添加Header
    mHttpURLConnection.setRequestProperty("Connection","Keep-Alive");
    //接收输入流
    mHttpURLConnection.setDoInput(true);
    //传递参数时需要开启
    mHttpURLConnection.setDoOutput(true);
    } catch (IOException e) {
    e.printStackTrace();
    }
    return mHttpURLConnection ;
    }

    因为我们要发送POST请求,所以在UrlConnManager类中再写一个postParams()方法用来组织一下请求参数并将请求参数写入到输出流中:

    public static void postParams(OutputStream output,List<NameValuePair>paramsList) throws IOException{
    StringBuilder mStringBuilder=new StringBuilder();
    for (NameValuePair pair:paramsList){
    if(!TextUtils.isEmpty(mStringBuilder)){
    mStringBuilder.append("&");
    }
    mStringBuilder.append(URLEncoder.encode(pair.getName(),"UTF-8"));
    mStringBuilder.append("=");
    mStringBuilder.append(URLEncoder.encode(pair.getValue(),"UTF-8"));
    }
    BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));
    writer.write(mStringBuilder.toString());
    writer.flush();
    writer.close();
    }

    接下来我们添加请求参数,调用postParams()方法将请求的参数组织好传给HttpURLConnection的输出流,请求连接并处理返回的结果:

    private void useHttpUrlConnectionPost(String url) {
    InputStream mInputStream = null;
    HttpURLConnection mHttpURLConnection = UrlConnManager.getHttpURLConnection(url);
    try {
    List<NameValuePair> postParams = new ArrayList<>();
    //要传递的参数
    postParams.add(new BasicNameValuePair("username", "moon"));
    postParams.add(new BasicNameValuePair("password", "123"));
    UrlConnManager.postParams(mHttpURLConnection.getOutputStream(), postParams);
    mHttpURLConnection.connect();
    mInputStream = mHttpURLConnection.getInputStream();
    int code = mHttpURLConnection.getResponseCode();
    String respose = converStreamToString(mInputStream);
    Log.i("wangshu", "请求状态码:" + code + "\n请求结果:\n" + respose);
    mInputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    最后开启线程请求网络:

    private void useHttpUrlConnectionGetThread() {
    new Thread(new Runnable() {
    @Override
    public void run() {
    useHttpUrlConnectionPost("http://www.baidu.com");
    }
    }).start();
    }

    这里我们仍旧请求百度,看看会发生什么?
    这里写图片描述

    mInputStream = mHttpURLConnection.getInputStream() 这句代码报错了,找不到文件。打开Fiddler来分析一下,不了解Fiddler和HTTP协议原理的请查看Android网络编程(一)HTTP协议原理这篇文章。

    我们的请求报文:
    这里写图片描述

    看来请求报文没有问题,再来看看响应报文:

    这里写图片描述

    报504错误,读取响应的数据报错,对于我们这次请求服务端不能返回完整的响应,返回的数据为0 bytes,所以mHttpURLConnection.getInputStream() 也读不到服务端响应的输入流。当然这次错误是正常的,百度没理由处理我们的这次POST请求。


    文章内容包括:
    1.HTTP简介
    2.HTTP/1.0和HTTP/1.1之间的区别
    3.HTTP的请求头、响应头和状态码
    4.Android中的HttpUrlConnection

    1.Http简介
    Http(Hypertext transfer protocol)定义了浏览器怎么向万维网服务器发送万维网文档,以及服务器怎么将文档发送给服务器。从层次上看,http是面向应用层协议的,它是万维网能够可靠交换文档的基础。
    http的工作流程
    当用户点击一个链接(假设URL为http://www.tsinghua.edu.cn/chn/yxsz/index.html ),所发生的事件流程:
    (1)浏览器分析连接所指向的页面的URL。
    (2)浏览器向DNS请求解析www.tsinghua.edu.cn的IP地址。
    (3)浏览器解析出服务器的IP地址。
    (4)浏览器与服务器建立TCP连接。
    (5)浏览器发出取文件指令:GET /chn/yxsz/index.html。
    (5)服务器给出响应,将文件index.html发送给浏览器。
    (6)释放TCP连接。
    (7)浏览器显示index.html的所用信息。
    Http的特点
    (1)支持客服/服务器(C/S)模式
    (2)简单快速,客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、POST、HEAD。每种方法规定了与服务器的连接不同,由于HTTP协议简单,使得HTTP服务器的程序规模更小、因而通信更快。
    (3)HTTP是无连接的。无连接意味者HTTP每次只处理一个请求,服务器处理完处理完客户的请求,并且收到客户的应答后,即断开连接,可以节省传输时间。
    (4)HTTP是无状态的。无状态意味者HTTP协议对于事务没有记忆能力,缺少状态表示后续处理需要前面的信息,则它必须重传。这可能使它没次连接传输的信息量增大,另一方面、服务器在不需要先前信息就表现的非常快,同时是服务器更容易支持大量的并发的HTTP请求。
    PS:虽然HTTP是无连接的协议,但HTTP使用了面向连接的运输层协议TCP,因此保证了数据的可靠传输,HTTP不用考虑数据在传输过程中被丢弃了如何重传。
    2.HTTP/1.0和HTTP/1.1之间的区别
    HTTP/1.0的主要缺点是它使用非持续连接每请求一个文档需要两倍的RTT的开销。这时的协议如果一个主页有很多链接的对象(如图片),每个链接都需要建立新的TCP连接,那么每一次链接下载都会导致2×RTT的开销。
    HTTP/1.1协议很好的解决了这个问题,它使用了持续连接,万维网服务器在发送响应后的一段时间内仍然保持着这个连接,是同一个客户可以和该服务器传送后续的HTTP请求报文和响应报文。
    3.HTTP的请求头、响应头和状态码
    请求头(进入简书的请求头,可以通过Firfox浏览器通过开发者选项打开网络查看(快捷键ctrl+shift+Q))。

    GET http://www.jianshu.com/
    Host: www.jianshu.com
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Referer: https://www.google.com.hk
    Cookie: (略)
    Connection: keep-alive
    If-None-Match: W/"b4e2a47d84be2df34bb1d5b79be9c040"
    Cache-Control: max-age=0

    下面说下具体的含义:
    GET定义了请求的方法。同样的方法共有8种(下面会列出)。
    Host:初始URL中的主机和端口。
    User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。
    Accept:浏览器可接受的MIME类型。
    Accept-Charset:浏览器可接受的字符集。
    Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。
    Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。
    Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
    Cookie:这是最重要的请求头信息之一,HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
    Connection: 表示是否需要持久连接。如果Servlet看到这里的值为“Keep- Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一 点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
    Cache-Control:If-None-Match:如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改。
    Cache-Control:指定请求和响应遵循的缓存机制。
    8中请求方法解释(摘自:http://itbilu.com/other/relate/EkwKysXIl.html)
    GET
    请求会显示请求指定的资源。一般来说GET方法应该只用于数据的读取,而不应当用于会产生副作用的非幂等的操作中。GET方法请求指定的页面信息,并返回响应主体,GET被认为是不安全的方法,因为GET方法会被网络蜘蛛等任意的访问。
    HEAD
    方法与GET方法一样,都是向服务器发出指定资源的请求。但是,服务器在响应HEAD
    请求时不会回传资源的内容部分,即:响应主体。这样,我们可以不传输全部内容的情况下,就可以获取服务器的响应头信息。HEAD方法常被用于客户端查看服务器的性能。
    POST
    请求会向指定资源提交数据,请求服务器进行处理,如:表单数据提交、文件上传等,请求数据会被包含在请求体中。POST方法是非幂等的方法,因为这个请求可能会创建新的资源或/和修改现有资源。
    PUT
    请求会身向指定资源位置上传其最新内容,PUT方法是幂等的方法。通过该方法客户端可以将指定资源的最新数据传送给服务器取代指定的资源的内容。
    DELETE
    请求用于请求服务器删除所请求URI(统一资源标识符,Uniform Resource Identifier)所标识的资源。DELETE请求后指定资源会被删除,DELETE方法也是幂等
    的。
    CONNECT
    该方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。
    OPTIONS
    请求与HEAD类似,一般也是用于客户端查看服务器的性能。这个方法会请求服务器返回该资源所支持的所有HTTP请求方法,该方法会用''来代替资源名称,向服务器发送OPTIONS请求,可以测试服务器功能是否正常。JavaScript的XMLHttpRequest对象进行CORS跨域资源共享时,就是使用OPTIONS方法发送嗅探请求,以判断是否有对指定资源的访问权限。允许
    *
    TRACE
    请求服务器回显其收到的请求信息,该方法主要用于HTTP请求的测试或诊断。
    *
    响应头(同样是在请求简书首页的响应头

    Cache-Control: max-age=0, private, must-revalidate
    Connection: keep-alive
    Content-Encoding: gzip
    Content-Type: text/html; charset=utf-8
    Date: Sun, 19 Jun 2016 15:29:41 GMT
    Etag: W/"e9a43aabd740855cd3fe0097faf6180d"
    Server: nginx
    Set-Cookie: (略)
    Vary: Accept-Encoding
    X-Request-Id: ce26a795-7e99-4959-a498-45f689471d7f
    X-Runtime: 0.596683
    x-content-type-options: nosniff
    x-frame-options: DENY
    x-xss-protection: 1; mode=block

    Cache-Control指定请求和响应遵循的缓存机制。
    Connection:表示是否需要持久连接。
    Content-Encoding 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档 的下载时间。
    Content- Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置 Content-Type,因此HttpServletResponse提供了一个专用的方法setContentTyep。
    Date 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
    Etag 请求变量的实体标签的当前值。
    Server 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
    Set-Cookie 设置和页面关联的Cookie。
    Vary 告诉下游代理是使用缓存响应还是从原始服务器请求
    更为详细的请求头与响应头信息,请参考:HTTP Header 详解
    *
    状态码
    1XX :表示通知信息的,如请求收到了或正在处理。
    2XX :表示成功,如接收或知道了。
    3XX :表示重定向,如要完成还需采取进一步处理。
    4XX :表示客户的差错,如请求中有错误的语法或不能完成。
    5XX :表示服务器的差错,如服务器失效无法完成请求。

    4.Android中的HttpUrlConnection
    Android中的连接主要是通过HttpUrlConnection来完成的,下面将要从HttpUrlConnection使用、get和post传递参数、多线程下载三个方面来看HttpUrlClient的用法:
    (1)HttpUrlConnection的使用格式:
    URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp"); //将地址转换为URL
    URLConnection rulConnection = url.openConnection(); // 此处的urlConnection对象实际上是根据URL的请求协议(此处是http)生成的URLConnection类的子类HttpURLConnection,故此处最好将其转化为HttpURLConnection类型的对象 HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;
    设置HttpUrlClient的连接参数:
    // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在。http正文内,因此需要设为true, 默认情况下是false; httpUrlConnection.setDoOutput(true); //设置是否从httpUrlConnection读入,默认情况下是true; httpUrlConnection.setDoInput(true); // Post 请求不能使用缓存 httpUrlConnection.setUseCaches(false); // 设定传送的内容类型是可序列化的java对象 // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException) httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object"); // 设定请求的方法为"POST",默认是GET httpUrlConnection.setRequestMethod("POST"); // 连接,从上述第2条中url.openConnection()至此的配置必须要在connect之前完成, httpUrlConnection.connect();
    对于HttpUrlConnection在代码中的具体用法,看下面都是一样的用法,看过就懂了。
    (2)get和post方式传递参数
    get方式
    使用get方式传递参数关键在于URl,在代码中可以看出我们在url中附加了一些数据,实际上get方式就是在通过在url中附加数据来传递参数的,因此采用这种方式是很不安全的。
    private void doGet(){ try { url = url + "?name=" + URLEncoder.encode(name,"utf-8") + "&age=" + age; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { URL httpUrl = new URL(url); //新建URL对象 HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();//打开一个连接 conn.setRequestMethod("GET");//设置请求方法为GET conn.setReadTimeout(5000);//设置从服务器读取数据的超时限制为5秒 BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream()));//获取服务器传递的数据输入流 String str; StringBuffer sb = new StringBuffer(); //存储读取的数据 while((str = reader.readLine()) != null){//读取数据 sb.append(str); } System.out.println("result:"+sb.toString()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
    POST方式
    post传递参数的方式与get是不同的,它会将传递的数据写入到请求的正文中。
    private void doPost(){ try { URL HttpUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) HttpUrl.openConnection(); conn.setRequestMethod("POST"); conn.setReadTimeout(5000); OutputStream out = conn.getOutputStream(); //新建输出流对象 String content = "name="+name+"&age="+age;//传递对象 out.write(content.getBytes());//将传递对象转为字符流写入输出流中 //下面是对于服务器返回数据的处理 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuffer sb = new StringBuffer(); String str; while((str=reader.readLine())!=null){ sb.append(str); } System.out.println(sb.toString()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
    (3)多线程下载

    public class DownLoad {
    
    
    private Executor threadPool = Executors.newFixedThreadPool(3);
    
    private Handler handler;
    
    public DownLoad(Handler handler){
        this.handler = handler;
    }
    
    static class DownLoadRunnable implements Runnable {
    
        private String url;
    
        private String fileName; 
    
        private long start;
    
        private long end;
    
        private Handler handler;
    
        public DownLoadRunnable(String url,String fileName,long start,long end,Handler handler){
            this.url = url;
            this.fileName = fileName;
            this.start = start;
            this.end = end;
            this.handler = handler;
        }
    
        @Override
        public void run() {
            try {
                URL httpUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Range","bytes="+start+"-"+end);
                conn.setReadTimeout(5000);
    
                
                RandomAccessFile access = new RandomAccessFile(new File(fileName),"rwd");
                access.seek(start);
                InputStream in = conn.getInputStream(); 
                byte[] b = new byte[1024*4];
                int len=0;
                while((len=in.read(b))!=-1){
                    access.write(b,0,len);
                }
                
                if (access!=null){
                    access.close();
                }
                if (in!=null){
                    in.close();
                }
                
                Message msg = new Message();
                msg.what = 1;
                handler.sendMessage(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void loadFile(String url) {
        try {
            URL httpUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
            conn.setRequestMethod("GET");
            conn.setReadTimeout(5000);
            int count = conn.getContentLength();
            int block = count / 3; 
            String fileName = getFileName(url);
            File parent = Environment.getExternalStorageDirectory();
            File download = new File(parent,fileName);
    
            
            
            for (int i=0;i<3;i++){
                long start = i*block;
                long end = (i+1)*block-1;
                if (i==2){
                    end = count;
                }
                
                DownLoadRunnable runnable = new DownLoadRunnable(url,download.getAbsolutePath(),start,end,handler);
                threadPool.execute(runnable);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public String getFileName(String url){
        return url.substring(url.lastIndexOf("/")+1);
    }

    }



    简单介绍

    看了深入理解Android网络编程感觉不错。今天对Android网络编程进行了要点记录。


    内容

    Android基于网络技术和编程实践

    要点 定义 描写叙述



     IP协议
    用于报文交换网络的一种面向数据的协议 
    TCP协议传输控制协议,传输层通信协议。 
    UDP协议用户数据报协议。传输层协议。 
    SMTP协议简单邮件传输协议 
    SOCKET 套接字应用层与TCP/IP协议族通信的中间软件抽象层。

    类型有两种:TCP套接字和UDP套接字。

    TCP套接字 在保证可靠性上,採用超时重传和捎带确认机制,在流量控制上,採用滑动窗体协议;在拥塞控制上。採用慢启动算法。
    UDP套接字 将网络数据流量压缩成数据包的形式。
    FTP协议文件传输协议,传输协议的应用层。

    可直接操作Apache的包
    Telnet协议远程登陆服务的标准协议可直接操作Apache的包
    C++和JAVA 套接字的差别Socket是Winsock里的原始套接字开发接口Api。1、接口不同,java本身无socket通讯底层实现,而是调用系统底层的winsock api二次封装;C++更接近系统层面的winsock,能够进行很多其他的底层扩展和控制。
    2、java开发出来的能够在支持java虚拟机上执行。
    UDP和TCP差别 1、tcp可靠,udp不可靠
    2、tcp支持的应用协议有:telnet,ftp,smtp,tcp可用户数据传输量大
    3、udp支持的应用协议:nfs(网络文件系统),snmp(简单网络管理系统),dns(主域名称系统),tftp通用文件传输协议等,用户数据传输量少。


    4、tcp是java.net.ServerSocket(用于server端)和java.net.Socket(用于client);UDP是java.net.DatagramSocket。
    5、流模式与数据报模式:TCP保证数据正确性,UDP可能丢包;TCP 保证数据顺序。UDP不保证。


       


    Android基本Web技术和编程实践

    要点 定义 描写叙述
    HTTP协议分布式超媒体信息系统的应用层协议。
    http://主机[":"port][路径]
    特点:
    1、支持C/S模式
    2、简单高速
    3、灵活
    4、无连接
    5、无状态
    两类报文:请求报文,响应报文。

    HTTP编程
    支持的功能有:自己主动转向、https协议、代理server,方法(get、post、put、head、opption、connect)
    实现:数据请求,数据上传,数据删除等操作。
    可操作的类:HttpClient和URLConnection。

    JSONJavaScript对象表示法。轻量级的文本数据交换格式。

    可操作的类:
    JSONObject、JSonArray、JSONArray、JSONTokener、JSONStringer。
    SOAP简单对象訪问协议。应用层协议。

    包括的元素:Envelope、Header、Body、Fault。
    HTML超文本标记语言解析Html文档的方法有:
    1、正則表達式
    2、字符串定位
    3、HTML Parser解析器
    4、Jsoup解析器
    怎样加密?数据传输可加入某加密算法进行加密加密算法有:自己定义位移(其他)、MD5(不可逆)、对称加密(DES、AES)、非对称加密(RSA)
    可引入crypto包。
       

    Android常见网络接口编程

    要点 定义 描写叙述
    XML扩展性标记语音使用XmlSerializer创建XML文件
    DOM解析一种解析XML的方式,特点:将XML文件的全部内容以文档树的方式存放在内存中,然后用户使用DOM API遍历XML树、检索所需的数据。

    所需的类:
    DocumentBuilderFactory、Document、Element、NodeList.
    SAX解析一种解析XML的方式,特点:基于事件驱动,边载入边解析。所需的类:
    XMLReader、ContentHandler、DTDHandler、ErrorHandler、EntityResolver
    PULL解析同上 
    RSS简易信息聚合。一种描写叙述和同步站点内容的格式。订阅:博客、新闻。 
    Email编程顾名思义:发送邮件。1、使用系统自带的邮件服务。
    2、採用javamail功能包进行发送邮件。

    加解密加密是通过加密算法和加密密钥将明文转变为密文的过程,解密相反。1、Base64加密(字符表示二进制数据)
    2、DES 是数据加密标准
    3、AES是高级加密标准
    4、MD5使用确保信息传输完整性
    OAuth认证一个开放标准。同意用户第三方使用。四个步骤:
    1、获取未授权的请求token
    2、获取用户授权的请求token
    3、用授权的请求token换认证token
    4、使用认证token訪问
    DOM和SAX的差别载入方式不同。DOM一次性载入全部内容。SAX边载入边读取。

     
       


    Android网络模块编程

    要点 定义 描写叙述
    USB编程通用串行总线,一种主从结构。涉及的类:
    UsbManager、UsbAccessory、UsbDevice、UsbEndpoint
    WIFI编程802.11b标准,无线通信的工业标准,特点:速度快、可靠、距离远。
    wifi直连技术是通过wifi直接互通。

    相关类:WirelessSettings、WifiSettings、AccessPointDialog、WifiEnabler、WifiLayer、WifiManager、WifiState、WifiService、WifiMonitor、WifiNativie、ScanResult、WifiInfo、wifiConfiguration。


    用户角度看五层:硬件驱动程序、wpa_supplicant、JNI、Wifi Api、WifiSettings应用程序。
    直连涉及的类:WifiP2pManager

    蓝牙编程一种支持设备短距离通信的无线技术涉及的类:BluetoothAdapter、BluetoothDevice、BluetoothSocket
    NFC编程近距离无线通信的技术。3种工作模式:主动、被动、双向。应用:接触通过、接触支付、接触连接、接触浏览。涉及的类:NfcAdapter、NdefMessage、NdefRecord
       

    基于Sip协议的Voip应用

    要点 定义 描写叙述
    sip协议会话发起协议。用于建立、改动和终止包括视频、语音、即时通信、在线游戏和虚拟现实等多媒体元素在内的交互会话。应用层的信令控制协议。
    使用什么协议传输的?UDP协议和TCP协议 
    H.323协议和SIp协议的比較1、H.323採用ASN.1和压缩编码规则的二进制方法表示其消息,sip基于文本协议。
    2、h.323由多点控制单元,全部终端都向mcu发送控制消息。sip是分布式的呼叫模型,具备组播功能。
     
    sip会话的构成?四个组件:
    1、SIP用户代理(终端设备)
    2、SIP注冊server(包括域中全部用户代理的位置的数据库)
    3、SIP代理server(接口UA的会话请求并查询SIP注冊server,获取收件方UA的地址信息)
    4、SIP重定向server(同意Sip代理server讲sip会话邀请信息定向到外部域)
     
       

    基于XMPP协议的即时通信

    要点 定义 描写叙述
    XMPP协议可扩展消息处理现场协议一种以xml为基础的开放式实时通信协议。

    Android的XMPPclient地址http://asmack.freakempire.de/ 
       


    Android对HTML的处理

    要点 定义 描写叙述
    HTML处理关键类Android HTML处理关键类在源代码frameworks/base/core/java/android/webkit文件夹下 
    关键类以及描写叙述1、AccessibilityInjector 为WebView注入能够訪问的javaScript和其相关内容。


    2、AutoCompletePopup 依据输入内容自己主动不全
    3、BrowserFrame  对WebCore中Frame对象的java层封装。
    4、CacheManager Cache管理对象。
    5、CallbackProxy 处理WebCore与UI线程消息的代理类
    6、CerTool  WebView证书工具
    7、ClientCerRequestHandler  处理client证书请求
    8、ConsoleMessage  javaScript控制台消息
    9、Cookiemanager  Cookies管理对象
    10、CookieManagerClassic  Cookiemanager  扩展实现类
    11、CookieSyncManager  Cookies同步管理对象,负责同步RAM和FLASH之间的Cookies数据。


    12、DataSorter 日期排序
    13、DebugFlags 调试标志
    14、DevicemotionAndOrientationManager 实现DeviceMotion和DeviceOrientation
    15、DeviceMotionService 实现SensorEventListener接口。处理方向变化。
    16、Downloadlistener 下载监听
    17、FindActionModeCallback 搜索动作回调
    18、GeolocationPermissions WebView的地理位置JavaScript Api的权限管理
    19、GeolocationPermissionsClassic  GeolocationPermissions 扩展类。处理UI线程中调用的WebKit线程。


    20、GeolocationService 封装位置监听。
    21、HTML5Audio 音频支持类
    22、HTML5VideoFullScreen  全屏视频视图
    23、HTML5VideoInline 内嵌视频视图
    24、HTML5VideoView 浏览器视频视图
    25、HTML5VideoViewProxy 视频视图处理类
    26、HttpAuthHandler 处理http认证请求
    27、JWebCoreJavaBridge 用于java与webcore库中timer和Cookies对象交互的桥接
    28、JniUtil  JNI使用的有用类,用于获取cache文件夹等C代码无法直接获取的信息、以及读取资源包中的文件。
    29、JsPromptResult js结果提示,提示javascript执行结果。
    30、JsResult  js结果,用户交互。
    31、KeyStoreHandler 负责证书安装到系统密钥存储区。从网络读取证书传给CertTool。
    32、L10nUtils 负责字符串国际化

    33、MimeTypeMap MIME类型映射
    34、MockGeolocation 模拟地理位置信息
    36、MustOverrideException 扩展执行时错误
    37、OverScrollGlow 用于实现OverScroller结果
    38、Plugin  定义插件的类
    39、PluginData  插件数据
    40、PluginFullScreenHolder  获取插件视图的容器的大小。负责显示等操作。
    41、PluginList  维护插件列表
    42、PluginManager 插件管理类
    43、PluginStub WebView的实现插件的接口
    44、QuadF 定义一个四边形
    45、SearchBox 搜索对话框接口
    46、SearchBoxImpl 搜索对话框接口实现
    47、SelectActionModeCallback 选择动作回调
    48、SslCertLookupTable 存储用户是否使用一个证书的决定
    49、SslClientCertLookupTable 保存client证书的用户选择
    50、SslErrorHandler 处理SSL错误
    51、URLUtil URL使用处理类
    52、valueCallback 异步返回数据值的回调接口
    53、ViewManager 视图管理类,管理插件视图
    54、ViewStateSerializer WebView视图序列化和反序列化
    55、WebBackForwardList WebView对象中显示的历史数据列表
    56、WebBackForwardListClient 浏览历史处理的client接口
    57、WebChromeClient Chromeclient
    58、WebCoreThreadWatchdog WebCore看门狗
    59、WebHistoryItem 一条网页数据
    60、WebIconDatabase 图标数据库管理对象
    61、WebIconDatabaseClassic  WebIconDatabase 扩展类
    62、WebResourceResponse 封装资源的响应信息
    63、WebSettings WebView的管理设置数据。通过JNI接口从底层获取。
    64、WebStorage 数据库
    65、WebSyncManager 数据同步管理对象。用于RAM数据和FLASH数据的同步操作。
    66、WebTextView 在HTML文本输入控件激活时显示系统原生编辑组件。
    67、WebView 视图对象
    68、WebViewClient Web视图客户对象。在web视图中有事件产生时,该对象获得通知。


    69、WebViewDatabase 数据库
    70、WebViewFactory WebView嵌入Fragment中。
    71、WebViewFragment ebView嵌入Fragment中。


    72、ZoomControlBase 缩放控件接口。
    73、ZoomControlEmbedded 内置缩放控件。
    74、ZoomManager 维护WebView的缩放状态。

       


    Android 网络处理分析

    要点 定义 描写叙述
    网络处理关键类Android HTML网络处理关键类在源代码frameworks/base/core/java/android/net文件夹下 
    关键类以及描写叙述1、ConnectivityManager 用于查询网络连接的状态。
    2、Credentials UNIX身份信息
    3、DhcpInfo  一个Dhcp请求结果的对象
    4、LocalServerSocket  创建下行unix域套接字的非标准类
    5、LocalSocket  在unix域命名空间创建一个非serversocket
    6、LocalSocketAddress  socket地址
    7、MailTo  解析mailto协议格式的url
    8、NetworkInfo 描写叙述网络接口状态
    9、Proxy 訪问用户及默认代理设置的类
    10、SSLCertificateSocketFactory  实现了ssl操作的额外细节
    11、SSLSessionCache  ssl会话缓存
    12、TrafficStats  网络流量统计
    13、Uri   一个不可变的url引用
    14、Uri.Builder  创建url引用的辅助类
    15、UrlQuerySanitizer  过滤url查询
    16、UrlQuerySanitizer.IllegalCharacterValueSanitizer 用它们包括的字符过滤非法值
    17、UrlQuerySanitizer.ParameterValuePair 參数值对的简单元组
    18、VpnService  应用扩展和建立自己的vpn解决方式的基类
    19、VpnService.Builder  创建一个vpn接口的辅助类
     
    Android封装的http处理类1、AndroidHttpClient(本质上是Apache DefaultHttpClient类在Android上的实现)
    2、DefaultHttpClient(一个Httpclient)
    3、SSL认证信息处理类(SSL协议的实现与数字证书相关,涉及的类:SslCertificate、SslError)
    1、AndroidHttpClient不能在主线程中执行,DefaultHttpClient在主线程中执行。
    2、AndroidHttpClient通过静态方法newInstance获得实例。而DefaultHttpClient创建对象。
    3、DefaultHttpClient默认启动Cookie,但默认不保留Cookie,如要保留需添加CookieStore到HttpContext中。

    Android RTP协议实时传输协议。用来为ip网络的语音、图像、传真等多种实时传输的多媒体数据提供端到端的实时传输服务。


    RTP协议具体说明了传递音频和视频的标准数据包格式。

    涉及的类:AudioCodec、AudioStream、AudioGroup、RtpStream。




    一、TCP/IP协议介绍

    在介绍HTTP协议之前,先简单说一下TCP/IP协议的相关内容

    TCP/IP协议是分层的,从底层至应用层分别为:物理层,链路层,网络层,传输层和应用层

    \

    从应用层至物理层,数据是一层层封装,封装的方式一般都是在原有的数据的前面加一个数据控制头,数据封装格式如下:

    \

    其中,对于TCP传输协议,客户端在与服务器建立连接前需要经过三次握手,过程如下:

    \

    其中,

    SYN是请求同步的意思,synchronize(同步)的缩写

    ACK是确认同步的意思,acknowledgement(确认)的缩写

    ---TCP(Transmission Control Protocol)传输控制协议---

    TCP是主机对主机层的传输控制协议,提供可靠的连接服务

    TCP的三次握手

    第一次握手:

    建立连接时,客户端A发生SYN包(SYN=j)到服务器B

    并进入SYN_SEND状态,等待服务器B确认

    第二次握手:

    服务器B收到SYN包,必须确认客户A的SYN,ACK=j+1

    同时自己也发送一个SYN包,SYN=k

    即,SYN+ACK包,此时服务器进入SYN_RECV状态

    第三次握手:

    客户端A收到服务器B的SYN+ACK包

    向服务器B发送确认包ACK(ACK=k+1)

    此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手

    TCP的四次挥手

    客户端A发送一个FIN.用来关闭客户A到服务器B的数据传送(报文段4)

    服务器B收到这个FIN. 它发回一个ACK,确认序号为收到的序号+1(报文段5)。和SYN一样,一个FIN将占用一个序号

    服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)

    客户端A发回ACK报文确认,并将确认序号设置为序号加1(报文段7)

    二、HTTP协议

    超文本传输协议(Hypertext Transfer Protocol,简称HTTP协议)是应用层协议

    HTTP协议格式比较简单,格式如下

    \

    HTTP最基本的方法有4种

    GET,查,一般用于获取/查询资源信息

    GET是向服务器发索取数据的一种请求

    安全的,该操作用于获取信息而非修改信息

    冪等的,对同一URL的多个请求应该返回同样的结果

    GET请求会附在URL之后,就是把数据放置在HTTP协议头中

    以?分隔URL和传输数据,参数之间以&相连,空格转换为+,中文字符改为该符号以16进制表示的ASCII

    POST,改,一般用于更新资源信息

    POST是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为“GET”

    实质上,GET和POST只是发送机制不同,并不是一个取一个发!

    POST把提交的数据放置在HTTP包的包体中

    POST的安全性比GET要高。通过GET提交数据,用户名密码将明文出现在URL上

    PUT,增

    DELETE,删




    4、Android代码实现WAP方式联网

    0.  前言

    无论是移动、联通还是电信,都至少提供了两种类型的的APNWAP方式和NET方式

    其中NET方式跟WIFI方式一样,无需任何设置,可自由访问所有类型网站,而WAP方式需要手机先设置代理服务器和端口号等信息,并且只能访问HTTP协议类型的网站。本篇将介绍如何在代码中实现WAP方式联网。

     

    1.  准备知识

    国内三大运营商关于WAPNET的信息如下:

    1移动的WAP名称是CMWAPNET名称是CMNET

    2联通的WAP名称是UNIWAPNET名称是UNINET;联通3GWAP名称是3GWAPNET名称是3GNET

    3电信的WAP名称是CTWAPNET名称是CTNET

    其中三家运营商WAP端口均为80,移动和联通的WAP代理服务器都是10.0.0.172,电信的WAP代理服务器是10.0.0.200

     

    在Android系统中,对于获取手机的APN设置,需要通过ContentProvider来进行数据库查询,查询的URI地址如下。

    [java] view plain copy
    1. //取得全部的APN列表:content://telephony/carriers;  
    2. //取得当前设置的APN:content://telephony/carriers/preferapn;  
    3. //取得current=1的APN:content://telephony/carriers/current;  

    2.  代码中实现WAP联网

    下面我们的代码就是使用APNManager类获取当前首选的APN设置,并继承HttpClient实现我们自己的代理ProxyHttpClient

    首先来看下APNManager类的实现,这个类的主要功能是获得APN的代理服务器和端口号

    [java] view plain copy
    1. import android.content.ContentResolver;    
    2. import android.content.Context;    
    3. import android.database.Cursor;    
    4. import android.net.ConnectivityManager;    
    5. import android.net.NetworkInfo;    
    6. import android.net.Uri;    
    7.     
    8. public class APNManager {    
    9.     
    10.     public static final Uri PREFERRED_APN_URI;    
    11.     
    12.     private String mApn; // 接入点名称    
    13.     
    14.     private String mPort; // 端口号    
    15.     
    16.     private String mProxy; // 代理服务器    
    17.     
    18.     private boolean mUseWap; // 是否正在使用WAP    
    19.     
    20.     static {  //取得当前设置的APN  
    21.         PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");   
    22.     }    
    23.     
    24.     public APNManager(Context context) {    
    25.         checkNetworkType(context);    
    26.     }    
    27.     
    28.     /**  
    29.      * 获得当前设置的APN相关参数  
    30.      * @param context  
    31.      */    
    32.     private void checkApn(Context context) {    
    33.         ContentResolver contentResolver = context.getContentResolver();    
    34.         Uri uri = PREFERRED_APN_URI;    
    35.         String[] apnInfo = new String[3];    
    36.         apnInfo[0] = "apn";    
    37.         apnInfo[1] = "proxy";    
    38.         apnInfo[2] = "port";    
    39.         //使用ContentResolver获得游标对象,之后就是查询操作了  
    40.         //分别查询当前手机所设置的APN、Proxy和Port  
    41.         //如果手机的Proxy没有设置,则需要根据APN来决定当前应该连接的代理服务器地址和端口号  
    42.         Cursor cursor = contentResolver.query(uri, apnInfo, nullnullnull);    
    43.         if (cursor != null) {    
    44.             while (cursor.moveToFirst()) {    
    45.                 this.mApn = cursor.getString(cursor.getColumnIndex("apn"));    
    46.                 this.mProxy = cursor.getString(cursor.getColumnIndex("proxy"));    
    47.                 this.mPort = cursor.getString(cursor.getColumnIndex("port"));    
    48.     
    49.                 // 代理为空    
    50.                 if ((this.mProxy == null) || (this.mProxy.length() <= 0)) {    
    51.                     String apn = this.mApn.toUpperCase();    
    52.                         
    53.                     // 中国移动WAP设置:APN:CMWAP;代理:10.0.0.172;端口:80    
    54.                     // 中国联通WAP设置:APN:UNIWAP;代理:10.0.0.172;端口:80    
    55.                     // 中国联通WAP设置(3G):APN:3GWAP;代理:10.0.0.172;端口:80    
    56.                     if ((apn.equals("CMWAP")) || (apn.equals("UNIWAP")) || (apn.equals("3GWAP"))) {    
    57.                         this.mUseWap = true;    
    58.                         this.mProxy = "10.0.0.172";    
    59.                         this.mPort = "80";    
    60.                         break;    
    61.                     }    
    62.                         
    63.                     // 中国电信WAP设置:APN(或者接入点名称):CTWAP;代理:10.0.0.200;端口:80    
    64.                     if (apn.equals("CTWAP")) {    
    65.                         this.mUseWap = true;    
    66.                         this.mProxy = "10.0.0.200";    
    67.                         this.mPort = "80";    
    68.                         break;    
    69.                     }    
    70.                         
    71.                 }    
    72.                 this.mPort = "80";    
    73.                 this.mUseWap = true;    
    74.                 break;    
    75.             }    
    76.     
    77.         }    
    78.     
    79.         this.mUseWap = false;    
    80.         cursor.close();    
    81.     }    
    82.     
    83.     /**  
    84.      * 检测当前使用的网络类型是WIFI还是WAP  
    85.      * @param context  
    86.      */    
    87.     private void checkNetworkType(Context context) {    
    88.         NetworkInfo networkInfo = ((ConnectivityManager) context    
    89.                 .getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();    
    90.         if (networkInfo != null) {    
    91.             if (!"wifi".equals(networkInfo.getTypeName().toLowerCase())) {    
    92.                 checkApn(context);    
    93.                 return;    
    94.             }    
    95.             this.mUseWap = false;    
    96.         }    
    97.     }    
    98.     
    99.     /**  
    100.      * 判断当前网络连接状态  
    101.      * @param context  
    102.      * @return  
    103.      */    
    104.     public static boolean isNetworkConnected(Context context) {    
    105.         NetworkInfo networkInfo = ((ConnectivityManager) context    
    106.                 .getApplicationContext().getSystemService("connectivity"))    
    107.                 .getActiveNetworkInfo();    
    108.         if (networkInfo != null) {    
    109.             return networkInfo.isConnectedOrConnecting();    
    110.         }    
    111.         return false;    
    112.     }    
    113.     
    114.     public String getApn() {    
    115.         return this.mApn;    
    116.     }    
    117.     
    118.     public String getProxy() {    
    119.         return this.mProxy;    
    120.     }    
    121.     
    122.     public String getProxyPort() {    
    123.         return this.mPort;    
    124.     }    
    125.     
    126.     public boolean isWapNetwork() {    
    127.         return this.mUseWap;    
    128.     }    
    129. }    

    通过APNManager类获取到或者设置好当前手机的WAP设置的代理和端口之后,就可以构造我们自己的代理类了,这个类定义为ProxyHttpClient,在该类的构造函数中,首先获得APNManager的实例,然后获取到APNManager类中的信息,即获取代理服务器proxy和端口值port通过这两个参数构造HttpHost实例,并将host实例设置为ConnRouteParams.DEFAULT_PROXY的值。具体实现如下:

    [java] view plain copy
    1. import android.content.Context;    
    2. import android.text.TextUtils;    
    3. import android.util.Log;    
    4.     
    5. import org.apache.http.HttpHost;    
    6. import org.apache.http.conn.params.ConnRouteParams;    
    7. import org.apache.http.impl.client.DefaultHttpClient;    
    8. import org.apache.http.params.HttpConnectionParams;    
    9. import org.apache.http.params.HttpParams;    
    10. import org.apache.http.params.HttpProtocolParams;    
    11.     
    12. public class ProxyHttpClient extends DefaultHttpClient {    
    13.         
    14.     private static final int HTTP_TIMEOUT_MS = 30 * 1000;    
    15.         
    16.     private static final int BUFFER_SIZE = 1024 * 8;    
    17.     
    18.     private static final String TAG = ProxyHttpClient.class.getSimpleName();    
    19.     
    20.     private RuntimeException mLeakedException = new IllegalStateException("ProxyHttpClient created and never closed");    
    21.     
    22.     private String mPort;    
    23.     
    24.     private String mProxy;    
    25.     
    26.     private boolean mUseWap;    
    27.     
    28.     public ProxyHttpClient(Context context) {    
    29.         this(context, nullnull);    
    30.     }    
    31.     
    32.     public ProxyHttpClient(Context context, APNManager manager) {    
    33.         this(context, null, manager);    
    34.     }    
    35.     
    36.     public ProxyHttpClient(Context context, String userAgent) {    
    37.         this(context, userAgent, null);    
    38.     }    
    39.     
    40.     public ProxyHttpClient(Context context, String userAgent, APNManager manager) {    
    41.         if (manager == null) {    
    42.             manager = new APNManager(context);    
    43.         }    
    44.             
    45.         this.mUseWap = manager.isWapNetwork();    
    46.         this.mProxy = manager.getProxy();    
    47.         this.mPort = manager.getProxyPort();    
    48.         if (this.mUseWap) {    
    49.             HttpHost host = new HttpHost(this.mProxy, Integer.valueOf(this.mPort).intValue());    
    50.             getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, host); // 设置代理    
    51.         }    
    52.         HttpConnectionParams.setConnectionTimeout(getParams(), HTTP_TIMEOUT_MS);    
    53.         HttpConnectionParams.setSoTimeout(getParams(), HTTP_TIMEOUT_MS);    
    54.         HttpConnectionParams.setSocketBufferSize(getParams(), BUFFER_SIZE);    
    55.         if (!TextUtils.isEmpty(userAgent)) {    
    56.             HttpProtocolParams.setUserAgent(getParams(), userAgent);    
    57.         }    
    58.     }    
    59.     
    60.     public void close() {    
    61.         if (this.mLeakedException != null) {    
    62.             getConnectionManager().shutdown();    
    63.             this.mLeakedException = null;    
    64.         }    
    65.     }    
    66.     
    67.     protected HttpParams createHttpParams() {    
    68.         HttpParams params = super.createHttpParams();    
    69.         HttpProtocolParams.setUseExpectContinue(params, false);    
    70.         return params;    
    71.     }    
    72.     
    73.     protected void finalize() throws Throwable {    
    74.         super.finalize();    
    75.         if (this.mLeakedException != null) {    
    76.             Log.e(TAG, "Leak found"this.mLeakedException);    
    77.         }    
    78.     }    
    79. }    

    展开全文
  • UA

    2014-08-06 16:13:43
    User-Agent就是客户端浏览器等应用程序使用的一种特殊的网络协议,在每次浏览器(邮件客户端/搜索引擎蜘蛛)进行 HTTP 请求时发送到服务器,服务器就知道了用户是使用什么浏览器(邮件客户端/搜索引擎蜘蛛)来访问的...
    什么是User agent?

    User-Agent就是客户端浏览器等应用程序使用的一种特殊的网络协议,在每次浏览器(邮件客户端/搜索引擎蜘蛛)进行 HTTP 请求时发送到服务器,服务器就知道了用户是使用什么浏览器(邮件客户端/搜索引擎蜘蛛)来访问的。既然是人为规定的协议,那么就是说不管什么浏览器,默认的UA都是可以更改的。有时候为了达到一些不可告人的目的,我就经常需要更改一下UA的设置,比如伪装一下浏览器类型,比如把浏览器伪装成手机上网。

    只要修改浏览器的User agent(后面简称UA),就可以骗过服务器,打开的网页就是手机网页!
    这个源码内的UA我使用的是iPhone浏览器的,也可以随意修改为其他的电脑浏览器或者其他手机浏览器的UA!
    更多的UA可以上http://www.ua123.net或者http://www.show-ip.net/browserinfo/进行查询

    展开全文
  • shell中的curl网络请求

    千次阅读 2017-07-03 17:59:08
    3、发送网络请求信息 GET方式请求: curl example.com/form.cgi? data =xxx 如果这里的 URL 指向的是一个文件或者一幅图都可以直接下载到本地 POST方式请求: //数据和网址分开,需要使用 '--data'...

    curl 是利用URL语法在命令行下工作的文件传输工具,1997年首次发行,支持文件上传和下载,结合shell脚本体验更棒。但按照传统习惯称 curl 为下载工具。

    curl 支持的通信协议有 有FTPFTPSHTTPHTTPSTFTPSFTP 等等,支持的平台有 Linux、MacOSX、Darwin、Windows、DOS、FreeBSD等等。

    一、curl的作用:

    1、查看网页源码

    denglibingdeMacBook-Pro-4: curl www.baidu.com
    
    <!DOCTYPE html>
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
    
    // 保存整个网页,使用 -o 处理
    denglibingdeMacBook-Pro-4: curl -o baidu www.baidu.com
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  2381  100  2381    0     0  77899      0 --:--:-- --:--:-- --:--:-- 79366

    2、查看头信息

    denglibingdeMacBook-Pro-4: denglibing$ curl -i www.baidu.com
    HTTP/1.1 200 OK
    Server: bfe/1.0.8.18
    Date: Mon, 03 Jul 2017 09:12:17 GMT
    Content-Type: text/html
    Content-Length: 2381
    Last-Modified: Mon, 23 Jan 2017 13:28:11 GMT
    Connection: Keep-Alive
    ETag: "588604eb-94d"
    Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
    Pragma: no-cache
    Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
    Accept-Ranges: bytes
    ...
    ...
    ...

    3、发送网络请求信息

    GET方式请求:

    curl example.com/form.cgi?data=xxx  如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地

    POST方式请求:

    //数据和网址分开,需要使用 '--data' 或者 '-d' 参数; curl默认使用GET,使用 '-X' 参数可以支持其他动词, 更多的参数使用 'man curl' 查看
    $ curl -X POST --data "data=xxx" example.com/form.cgi
    
    // '--user-agent' 字段,表表面客户端的设备信息:
    $ curl --user-agent "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89/mideaConnect MissonWebKit/4021/zh-Hans (AppStore) (4347701760)" http://www.example.com
    
    //使用 '--cookie' 参数,可以让curl发送cookie
    $ curl --cookie "name=xxx" www.example.com
    
    //添加头信息,自行增加一个头信息。'--header' 或者 '-H' 参数就可以起到这个作用
    $ curl --header "Content-Type:application/json" http://example.com
    
    
    //提交文件作为请求信息 使用 '@文件名' 请求
    $ curl -X POST -H "Content-Type: text/xml" -d @denglibing.txt http://example.com
    
    //denglibing.txt:
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.webservices.com"><soapenv:Header/><soapenv:Body><ser:addEmpIdCardrecord><ser:empId>11622695,D58C6A25-C683-47D6-A18C-B7741284F632</ser:empId></ser:addEmpIdCardrecord></soapenv:Body></soapenv:Envelope>

    二、实例

    denglibingdeMacBook-Pro-4:~ denglibing$ curl https://api.github.com/users
    [
      {
        "login": "mojombo",
        "id": 1,
        "avatar_url": "https://avatars3.githubusercontent.com/u/1?v=3",
        "gravatar_id": "",
        "url": "https://api.github.com/users/mojombo",
        "html_url": "https://github.com/mojombo",
        "followers_url": "https://api.github.com/users/mojombo/followers",
        "following_url": "https://api.github.com/users/mojombo/following{/other_user}",
        "gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
        "organizations_url": "https://api.github.com/users/mojombo/orgs",
        "repos_url": "https://api.github.com/users/mojombo/repos",
        "events_url": "https://api.github.com/users/mojombo/events{/privacy}",
        "received_events_url": "https://api.github.com/users/mojombo/received_events",
        "type": "User",
        "site_admin": false
      }
    ]

    当然,既然这些请求是在命令行中执行,完全可以写成shell脚本,来处理一系列的工作,比如多个请求,而shell脚本在Mac中,可以使用定时任务触发,进而完成一系列的自动化工作。

    三、相关链接

    curl网站开发指南

    How do I POST XML data with curl

    展开全文
  • ) httpbin是一个http测试网站,很好用 python多数是操作bytes格式数据,无论入参data还是返回数据,都是bytes格式,而我们使用得多是我们熟悉的类型比如int、string、列表等,网络请求返回的也是bytes数据,我们要...
  • UA的全称是User-Agent,中文名为用户代理,是Http请求协议中请求头的一部分,这里的请求包括GET请求和POST请求 user-agent的获取和设置 webView获取user-agent WebView webView = findViewById(R.id.webview);...
  • 文章目录一、引入二、使用方式2.1 get请求2.2 post请求2.2.1 post请求提交String、文件2.2.2 ...OkHttp3是由square公司开发,Android中公认最好用的网络请求框架,在接口封装上做的简单易用,GitHub地址。 它有以下...
  • ios 网络请求问题

    千次阅读 2016-06-29 11:11:15
    TCP,IP,HTTP,SOCKET区别和联系 网络由下往上分为: 对应   物理层--  数据链路层-- 网络层-- IP协议 传输层-- TCP协议 会话层-- 表示层和应用层-- HTTP
  • okhttp拦截器网络请求

    2017-09-28 21:17:35
    导入依赖: compile 'com.squareup.okhttp3:okhttp:3.9.0' 写拦截器 public class HttpInterceptor implements Interceptor { private static final String UA = "User-Agent"; @Override public Response
  • 爬虫中一个基于网络请求的模块 安装 pip install requests 作用:模拟浏览器发起请求 爬虫流程 1,指定url 2,发起请求 3,获取相应数据(爬取到的页面源码数据) 4,持久化存储 案例一 # -*- coding: utf-8 -*...
  • vue 中使用 Axios 发起 get 请求 vue 中使用 Axios 发起 post 请求 1 简述 Axios是一个基于Promise(ES6中用于处理异步的)的HTTP库,用于浏览器和node.js中。 导包地址 <script src=...
  • 前几篇文章写了关于React-Native中...今天要写的是关于React-Native中的网络请求的实现。 1.get的请求方式的实现 //get请求 static get(url, callback) { fetch(url) .then((response) => response.text())
  • 如题,判断请求Request是移动端访问还是PC端访问,贴代码 import javax.servlet.http.HttpServletRequest; public class CommonUtil { public void index(HttpServletRequest request) { String ua = request....
  • Python网络请求模块 urllib Urllib 库,它是 Python 内置的 HTTP 请求库,也就是说我们不需要额外安装即可使用,它包含四个模块 第一个模块 request,它是最基本的 HTTP 请求模块,我们可以用它来模拟发送一请求,就...
  • iOS网络数据请求

    千次阅读 2016-05-06 21:52:56
    //网络请求失败 - ( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error { NSLog (@ "请求出错----%@" ,error); } iOS7之后请求变化 NSURLSession get请求(block) ...
  • iOS http网络请求相关知识总结

    千次阅读 2015-09-19 09:56:28
     AFNetWorking是非常轻便的网络请求第三方库,其于NSURLConnect、NSURLSession的基础上再封装一层,使调用网络请求更简单,特别是上传文件的表单上的封装。  MKNetWorkKit也是轻便的网络请求第三方库,其...
  • Google Chrome扩展程序,用于修改对Facebook的网络请求中的HTTP标头 FaceHate是作为概念证明扩展而创建的,供Google Chrome修改HTTP标头: 用户代理(UA) 曲奇饼 引用HTTP数据包中发送到Facebook服务器(以提高...
  • 看其他请求,可以看出,在闪退后再次进入登录页,以及登录后的浏览器端的cookie的sessionId都是同一个id,所以一切正常. 而闪退前的登录页请求中,浏览器所发送的id发生了3次变化.显然有不正常的事情在里面. 但是在...
  • uc7 uc8 请求头里都有android字样 3、 QQ浏览器 user-agent = MQQBrowser/3.4/Adr (Linux; U; 2.3.7; zh-cn; GT-I9000 Build/MIUI.2.4.13;480*800)  没有android字样,只显示android系统版本号...
  • URL,敲击回车访问这个页面,观察一下在这个过程中发生了怎样的网络请求? F12 -> Network. 这一个条目的各列分别代表: 第一列 Name,即 Request 的名称。一般会用URL的最后一部分内容当做名称。 第二列 ...
  • 网络爬虫中Jsoup请求url

    千次阅读 2017-02-11 09:45:49
    它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。下面是我写的一个案例欢迎大家参考:import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes....
  • 通过Charles抓包发现,请求中有一个验签参数signature,每次请求网络都会变化。 请求地址: http://xxxx.xxxxxx.com/api/article/v2/get_category 参数: { "content":{"muid" :"f7e2cb93-5cf3-4b9f-a035-30555c13a...
  • Webview 非http或者https的网络请求拦截

    万次阅读 2016-12-29 13:51:39
    这样可以减少页面的网络请求次数。 LOAD_CACHE_ELSE_NETWORK:只要缓存可用就加载缓存,哪怕它们已经过期失效。如果缓存不可用就从网络上加载数据。 LOAD_NO_CACHE:不加载缓存,只从网络加载数据。 LOAD_CACHE_ONLY...
  • 什么是OPC UA

    万次阅读 多人点赞 2018-09-06 14:38:29
    OPC UA(Unified Architecture,统一架构)是下一代的OPC 标准,通过提供一个完整的,安全和可靠的跨平台的架构,以获取实时和历史数据和时间。 OPC UA基于OPC基金会提供的新一代技术,提供安全,可靠和独立于厂商...
  • 特殊SIP UA

    2020-08-25 16:16:43
    状态呈现代理(presence agent,PA)是SIP UA的一种,它能够接收订阅请求并生成SIP事件规范所定义的状态通知。PA支持状态呈现包,响应SUBSCRIBE请求,并发送NOTIFY请求。有些时PA还通过PUBLISH请求向事件状态合成器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,833
精华内容 5,533
关键字:

网络请求ua