android中的网络请求(以注册登陆为例)

本文深入探讨了HTTP协议的基本概念,包括其应用层协议性质、客户端与服务器建立连接的流程,以及与Socket的区别。详细解释了三次握手的过程,并介绍了HTTP请求头和响应头的相关信息。此外,文章还通过代码实例展示了GET和POST方法在实现登陆过程中的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Http协议

http协议:定义的浏览器向万维网服务器请求万维网文档,以及服务器把文档传递给浏览器。http是面向应用层协议。在万维网上能够可靠的交换文件(包括文本,声音,图像等)。


2、客户端与服务器建立连接流程。

1.客户端 通过发送url发出请求。比如:http://www.baidu.com

  1. htttp—-请求的协议;(常见的http和https协议)
  2. www.baidu.com—-通过域名解析的Ip地址(ip地址难以记忆)
  3. 目录下的文件名等。(可以省略)

2.在服务器收到请求后,做出相应的响应处理,返回成功或者错误的信息,包括MIME信息。

3.客户端在收到服务器返回的信息后通过浏览器显示在屏幕上,然后断开链接。


4、Http与Socket的区别:

http://www.cnblogs.com/lwbqqyumidi/archive/2012/11/04/2754415.html
HTTP:超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据。HTTP协议详细规定了浏览器与服务器之间相互通信的规则,是万维网交换信息的基础。HTTP是基于请求-响应形式并且是短连接,并且是无状态的协议。针对其无状态特性,在实际应用中又需要有状态的形式,因此一般会通过session/cookie技术来解决此问题。

Socket:Socket不属于协议范畴,而是一个调用接口(API),Socket是对TCP/IP协议的封装,通过调用Socket,才能使用TCP/IP协议。Socket连接是长连接,理论上客户端和服务器端一旦建立连接将不会主动断开此连接。Socket连接属于请求-响应形式,服务端可主动将消息推送给客户端。


http连接:http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉;
socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。


Socket适用场景:网络游戏,银行交互,支付。
http适用场景:公司OA服务,互联网服务。


4、建立连接的三次握手

三次握手主要是为了防止过期的链接再次传给被连接的主机。

比如a主机要连接到b主机,a向b发起请求链接,由于某种原因,没有链接上,于是a
又向b发送一条请求,当b 收到a的第二次请求时,建立链接,然后断开。
这时候,a发出的第二条请求也到达b这时候,又进行的连接。其实该连接已经过期。

这里写图片描述
SYN:同步序列编号(Synchronize Sequence Numbers)
ACK:确认标志(Acknowledgement Number)
三次握手:
第一次握手:客户端发送syn到服务器,等待服务器确认。(syn=x)
第二次握手:服务器收到syn包,必须确认客户端的syn(ack=x+1),同时发送一个自己的syn包syn=y
第三次握手:客户端收到syn+ack后,再次向服务器发送确认包ack(y+1),发送后三次握手完成,建立连接。


5、Http的请求头信息

从浏览器中输入http://www.baidu.com得到下面的信息。
这里写图片描述


1、请求的内容:

- 请求地址:Remote Address

Remote Address:119.75.217.109:443

- 请求的RUL:Request URL

Request URL:https://www.baidu.com/

- 请求的方式:Request Method

Request Method:GET

- 返回码:Status Code

200 OK

2、请求头内容:

- Accept:浏览器可接受的MIME类型。

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
MIME类型:text/html,application/xhtml+xml,application/xml
Text:文本类型;
text/html:表示html文档;
Application:表示传输应用程序数据或者二进制数据;
application/xhtml+xml表示xhtml文档
application/xml表示xml文档

- Accept-Charset:浏览器接收的字符编码
Accept-Encoding:gzip,deflate(gzip是指可压缩的,deflate是指使用了lz77算法与哈夫曼编码的一个无损数据压缩文件格式)

- Accept-Language:浏览器接收的语言
Accept-Language:zh-CN,zh;q=0.8(zh-ch表示简体中文,zh表示中文,q权重系数,请求更倾向于“;”前的表示内容)
- Cache-Control:是否有缓存
Cache-Control:max-age=0

- Connection*户端与服务器的链接类型
Connection:keep-alive(keep-alive表示持久连接)

2、响应头内容:

- Cache-Control缓存
Cache-Control:private

- Connection:保持链接
Connection:keep-alive
- Content-Encoding:支持的编码
Content-Encoding:gzip
- Content-Type:
Content-Type:text/html;charset=utf-8

6、HttpUrlConnection相关的属性。

 HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();  

        // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在 http中。

    urlConn.setDoOutput(true);  

    // 设置是否从httpUrlConnection读入,默认情况下是true;  
    urlConn.setDoInput(true);  

    // Post 请求不能使用缓存 
    urlConn.setUseCaches(false);  

    // 设定传送的内容类型是可序列化的java对象  
    // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)  
    urlConn.setRequestProperty("Content-type","application/x-java-serialized-object");  

    // 设定请求的方法为"POST",默认是GET  
    urlConn.setRequestMethod("POST");  

    // 连接,上面对urlConn的所有配置必须要在connect之前完成,  
    urlConn.connect();  

7、得到向服务器提交数据的上传进度

当我们要获取上传进度的时候,一般会立即显示上传100%的进度,其实文件还在上传。
上面conn的连接中有这样一个配置。有个setUseCaches(false)这样一个属性设置。其实这个值是不起作用的,stackoverflow有许多相关的资料。api上说这个设置没有缓存,但实际上还是有缓存的,比如说向服务器提交图片或者文件,得到的是一个不真实的进度,原因是使用httpurlconnection向服务器提交数据,它都会进行缓存。也就是以这种方式得不到真正的上传进度。

如何得到真实的上传进度。
(1)conn.setUseCahces(false):不起作用。
(2)conn.setChunkedStreamingMode(1024);在api上描述的是可能不适配后台服务器,我测试的php服务器,分段传输也没有作用。
(3)conn.setFixedLengthStreamingMode(contentLength);经测试也没用作用。
(4)换httpclient。
(5)用其他c++的类库。

8、从代码中理解get与post提交数据;

1、get方法实现登陆;

服务器上代码(myeclipse建立web项目,tomcat部署项目):
这里写图片描述这里写图片描述
服务器中的代码如下:
(1)jsp中写出服务器登陆界面。

<body>
    This is my JSP page.
    <br>
    <form action="ServletDemo" method="get">
        用户名:<input type="text" id="username" name="username" /> <br>
        密码: <input type="text" id="password" name="password" /> <br> <input
            type="submit" value="提交" />

    </form>
</body>

java代码判读用户名和密码,返回登陆成功或者失败。

public class ServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String username = req.getParameter("username");

        String password = req.getParameter("password");
        resp.setContentType("text/html;charset=utf-8");
        // 浏览器默认的编码是iso-8859-1转换成utf-8,如果不转换,会产生乱码。
        String name = new String(username.getBytes("iso-8859-1"), "utf-8");
        String pass = new String(password.getBytes("iso-8859-1"), "utf-8");
        System.out.println("username" + name);
        System.out.println("password" + pass);
        //如果登陆名是张三,密码是123,登陆成功,否则登陆失败。
        if ("张三".equals(name)&&pass.equals("123")) {
            resp.getWriter().write("登陆成功");
        } else
            resp.getWriter().write("用户名或密码错误");

    }
}

这里写图片描述
在android中请求服务器,从服务器中获取请求的结果,显示登陆成功,或者登陆失败。

public class MainActivity extends Activity {
    private EditText et_name;
    private EditText et_password;
    private Button btn_submit;
    private TextView tv_result;

    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            tv_result.setText(msg.obj + "");
            Toast.makeText(MainActivity.this, (String) msg.obj, 0).show();
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_name = (EditText) findViewById(R.id.et_name);
        et_password = (EditText) findViewById(R.id.et_pass);

        tv_result = (TextView) findViewById(R.id.tv_result);

        btn_submit = (Button) findViewById(R.id.btn_submit);
        // 用get的方式请求,把请求内容拼接到url后面。
        final String s = "http://192.168.1.103:8080/testServlet/ServletDemo?username=aaaa&password=1234";

        //Log.i("MainActivity", path);
        btn_submit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                final String username = et_name.getText().toString().trim();
                final String password = et_password.getText().toString().trim();
                Thread t = new Thread() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            final String path = "http://192.168.1.103:8080/testServlet/ServletDemo?username="
                                    + URLEncoder.encode(username) // 对提交的数据进行url编码
                                    + "&password="+password;
                            URL url = new URL(path);
                            HttpURLConnection conn = (HttpURLConnection) url
                                    .openConnection();
                            conn.setRequestMethod("GET");
                            conn.setReadTimeout(5000);
                            conn.setReadTimeout(5000);
                            if (conn.getResponseCode() == 200) {
                                InputStream is = conn.getInputStream();
                                String text = Utils.getTextFromStream(is);
                                Log.i("MainActivity", text);
                                // 发送消息,把服务器返回的本文弹出吐司显示
                                Message msg = handler.obtainMessage();
                                msg.obj = text;
                                handler.sendMessage(msg);
                            }
                        } catch (MalformedURLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        super.run();
                    }
                };
                t.start();
            }

        });

    }

}

工具类代码:

public class Utils {

    public static String getTextFromStream(InputStream is){

        try {
            int len = 0;
            byte[] b = new byte[1024];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while((len = is.read(b)) != -1){
                bos.write(b, 0, len);
            }

            String text = new String(bos.toByteArray());
            bos.close();
            return text;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

2、以post的方法提交请求。

package com.example.logindemo;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    private EditText et_name;
    private EditText et_password;
    private Button btn_submit;
    private TextView tv_result;

    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            tv_result.setText(msg.obj + "");
            Toast.makeText(MainActivity.this, (String) msg.obj, 0).show();
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_name = (EditText) findViewById(R.id.et_name);
        et_password = (EditText) findViewById(R.id.et_pass);

        tv_result = (TextView) findViewById(R.id.tv_result);

        btn_submit = (Button) findViewById(R.id.btn_submit);
        // 用get的方式请求,把请求内容拼接到url后面。
        // Log.i("MainActivity", path);
        btn_submit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                final String username = et_name.getText().toString().trim();
                final String password = et_password.getText().toString().trim();
                Thread t = new Thread() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            // final String s =
                            // "http://192.168.1.103:8080/testServlet/ServletDemo?username=aaaa&password=1234";
                            final String path = "http://192.168.1.103:8080/testServlet/ServletDemo";
                            URL url = new URL(path);
                            HttpURLConnection conn = (HttpURLConnection) url
                                    .openConnection();
                            conn.setRequestMethod("POST");
                            String text = "username="
                                    + URLEncoder.encode(username) + "&password="
                                    + password;
                            conn.setReadTimeout(5000);
                            conn.setReadTimeout(5000);
                            conn.setRequestProperty("Content-Type",
                                    "application/x-www-form-urlencoded");
                            conn.setRequestProperty("Content-Length",
                                    text.length() + "");
                            conn.setDoOutput(true);
                            conn.setDoInput(true);
                            OutputStream os=conn.getOutputStream();
                            //把提交的文件写到流中;
                            os.write(text.getBytes());

                            if (conn.getResponseCode() == 200) {
                                InputStream is = conn.getInputStream();
                                String s = Utils.getTextFromStream(is);
                                Log.i("MainActivity", text);
                                // 发送消息,把服务器返回的本文弹出吐司显示
                                Message msg = handler.obtainMessage();
                                msg.obj = s;
                                handler.sendMessage(msg);
                            }
                        } catch (MalformedURLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        super.run();
                    }
                };
                t.start();
            }

        });

    }

}

服务器与客户端代码下载地址
http://download.youkuaiyun.com/detail/androidxiaogang/9344051

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值