Java中的网络协议

OSI七层模型 TCP/IP四层模型
HTTP协议
HttpClient HttpURLConnection
TCP协议 UDP协议
Socket实现TCP通信
Socket实现UDP通信

为了使不通类型的计算机之间可以相互通信,国际化标准组织提出了OSI七层网络模型,从下到上分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。但是OSI七层网络模型仅仅用于实验室,并没有真正的使用它,实际的环境中用的是TCP/IP四层模型,TCP/IP四层网络模型包括:链路层、网络层、传输层、应用层。

链路层:
处理数据在物理介质(比如以太网)上的传输,网络驱动程序运行在该层,网络驱动程序隐藏了物理媒介的电气特性,为上层提供了统一的接口。
主要协议:
ARP协议:地址解析协议,根据IP地址获取物理地址。
RARP协议:逆地址解析协议,根据物理地址获取IP地址。

网络层:
网络层是TCP/IP模型的核心层,网络层主要是确定主机的通信路径,实现数据包的选路和转发。
主要协议:
IP协议(Internet Protocol):根据数据包目的IP地址选择如果投递该数据包。寻找合适的转发路由器,将该数据包交给路由器转发。
ICMP协议(Internet Control Message Protocol):主要用于检测网络的连接状态。如ping命令就是ICMP协议的应用。

传输层
为两台主机中的应用程序提供端到端的通信,只关心通信两端的信息,不关心数据包的传输过程。负责数据的转发、链路超时重连等。
主要协议:
TCP(Transmission Control Protocol)协议: 传输控制协议,为应用层提供可靠的、面向连接的、基于流的服务。
UDP(User Datagram Protocol)协议:用户数据报协议,为应用层提供不可靠的、无连接的、基于数据报的服务。

应用层:
基于其他三层网络协议,实现处理一些应用程序的逻辑和功能,如文件传输等。
主要协议:
HTTP协议:超文本传输协议,基于TCP,使用80或者8080端口。
FTP协议:文件传输协议,基于TCP,使用20或者21端口。
DNS(Domain Name Service):域名服务。

HTTP协议:
HTTP(Hypertext Transfer Protocol),基于TCP协议之上的请求/响应式协议,HTTP指定客服端与服务器如何建立连接、客服端如何从服务器获取数据、服务器如何响应请求、以及如何关闭连接等。
请求报文:
在这里插入图片描述
请求行组成:请求方法+空格+请求地址+http协议版本号+回车符+换行符
HTTP请求方法有8种:
GET:请求获取Request-URI所标识的资源
POST:在Request-URI所标识的资源后附加新的数据
HEAD:请求获取由Request-URI所标识的资源的响应消息报头
PUT: 请求server存储一个资源。并用Request-URI作为其标识
DELETE :请求server删除Request-URI所标识的资源
TRACE : 请求server回送收到的请求信息。主要用于測试或诊断
CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理server。
OPTIONS :请求查询server的性能。或者查询与资源相关的选项和需求
请求行后面是0个或多个请求报头。请求报头后面还有不可少的空行,如果是POST请求,空行后面还有请求数据。

响应报文:
在这里插入图片描述
状态行组成:http协议版本号+空格+响应状态代码。
响应状态代码:
100~199:指示信息,表示请求已接收,继续处理
200~299:请求成功。表示请求已被成功接收、理解、接受
300~399:重定向,要完毕请求必须进行更进一步的操作
400~499:client错误。请求有语法错误或请求无法实现
500~599:server端错误,server未能实现合法的请求
常见的响应状态代码:
200 OK:client请求成功
400 Bad Request:client请求有语法错误,不能被server所理解
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-- - - Authenticate报头域一起使用
403 Forbidden:server收到请求。可是拒绝提供服务
404 :请求资源不存在
500 Internal Server Error:server发生不可预期的错误
503 Server Unavailable:server当前不能处理client的请求。一段时间后可能恢复正常

Android中为我们提供了两个实现HTTP请求的类:HttpClient和HttpUrlConnection。
HttpClient:HttpClient是Apache提供的一个开源项目,HttpClient是一个接口,我们不能直接创建他的实例,可以通过它的实现类DefaultHttpClient或者AndroidHttpClient创建HttpClient对象。一个HttpClient请求大致分为以下几步:
1、创建HttpClient对象
2、创建请求对象:Get请求创建HttpGet对象,Post请求创建HttpPost对象。
3、调用HttpClient对象得execute方法获取返回的HttpResponse对象。
4、通过HttpResponse获取响应数据。
HttpClient发送Get请求:

    public static void httpClientGet(String url) {
        try {
            //创建HttpClient对象
            HttpClient httpClient = new DefaultHttpClient();
            //创建HttpGet对象
            HttpGet httpGet = new HttpGet(url);

            HttpParams params = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
            HttpConnectionParams.setSoTimeout(params, 10 * 1000);
            httpGet.setParams(params);

            //调用HttpClient对象的execute方法 获取返回的HttpResponse
            HttpResponse response = httpClient.execute(httpGet);

            //解析对应数据
            int state = response.getStatusLine().getStatusCode();
            Log.i(TAG, "httpClientGet-->state:" + state);
            if (state == 200) {
                HttpEntity entity = response.getEntity();
                String content = EntityUtils.toString(entity,"utf-8");
                Log.i(TAG, "content-->" + content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

HttpClient发送POST请求:

    public static void httpClientPost(String url, JSONObject jsonObject) {
        //构造消息实体
        try {
            HttpPost httpPost = null;
            HttpClient httpClient = new DefaultHttpClient();
            httpPost = new HttpPost(url);
            //设置请求超时
            HttpParams params = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
            HttpConnectionParams.setSoTimeout(params, 10 * 1000);
            httpPost.setParams(params);

            //设置请求超时
//            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10 * 1000);
//            httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10 * 1000);

            //构造消息头
            httpPost.setHeader("Content-type", "application/json; charset=utf-8");
            httpPost.setHeader("Connection", "Close");
            //构造消息实体
            StringEntity entity = new StringEntity(jsonObject.toString());
            entity.setContentEncoding("UTF-8");
            //发送数据
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            HttpResponse response = httpClient.execute(httpPost);
            int state = response.getStatusLine().getStatusCode();
            Log.i(TAG, "httpClientPost-->state:" + state);
            if (200 == state) {
                Header[] headers = response.getAllHeaders();
                for (Header header : headers) {
                    Log.i(TAG, "name:" + header.getName() + ",value:" + header.getValue());
                }
                HttpEntity contentEntity = response.getEntity();
                String content = EntityUtils.toString(contentEntity, "utf-8");
                Log.i(TAG, "content-->" + content);
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

HttpUrlConnection:一个轻量级的HTTP客服端,API简单,相对扩展容易,HttpUrlConnection的压缩和缓存机制可以有效的减少网络访问的流量。在Android2.3以前HttpUrlConnection存在一些BUG(如:对一个可读的InputStream调用close()方法时可能会导致连接池失效)网络访问基本用的是HttpClient,在Android2.3及以上HttpUrlConnection则是最好的选择,Google在Android6.0完全移除了HttpClient。
HttpUrlConnection发送GET请求:

public static void httpUrlConnectionGet(String connectUrl) {
        try {
            //获取URL对象
            URL url = new URL(connectUrl);
            //获取HttpURLConnection对象
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            //设置请求方式
            urlConnection.setRequestMethod("GET");
            //设置连接超时和读取超时
            urlConnection.setConnectTimeout(10 * 1000);
            urlConnection.setReadTimeout(10 * 1000);
            //以上配置需要在调用connect()方法前调用,之后调用不起作用。
            //建立连接 注意:这里仅仅是建立连接 当我们调用getInputStream()的时候 也会调用connect()方法
            urlConnection.connect();
            //处理数据
            int responseCode = urlConnection.getResponseCode();
            Log.i(TAG, "responseCode:" + responseCode);
            if (responseCode == 200) {
                InputStream is = urlConnection.getInputStream();
                StringBuilder builder = new StringBuilder();
                InputStreamReader reader = new InputStreamReader(is);
                int len = 0;
                char[] chars = new char[1024];
                while ((len = reader.read(chars)) != -1) {
                    builder.append(new String(chars, 0, len));
                }
                Log.i(TAG, "content:" + builder.toString());
                is.close();
                reader.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

HttpUrlConnection发送POST请求:post请求主要就是获取HttpUrlConnection的输出流getOutputStream(),之后往输出流中写入需要发送到服务端的数据。

    public static void httpUrlConnectionPost(String url, String body) {
        try {
            URL postUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(10 * 1000);
            connection.setReadTimeout(10 * 1000);
            //设置是否向HttpURLConnection 输出,默认为false
            connection.setDoOutput(true);
            //设置是否从HttpURLConnection读入,默认伟true
            connection.setDoInput(true);
            //post请求不能使用缓存
            connection.setUseCaches(false);
            //设置传送的内容类型是可序列号的Java对象
            //如果不设置 当服务端默认不是这种类型时会抛出异常
            connection.setRequestProperty("Content-type", "application/x-java-serialized-object");
            connection.connect();
            //获取HttpURLConnection的输出流
            OutputStream os = connection.getOutputStream();
            //向输出流中写入数据
            BufferedWriter br = new BufferedWriter(new OutputStreamWriter(os));
            br.write(body);
            br.close();
            //处理返回结果
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK){
                InputStream is = connection.getInputStream();
                InputStreamReader reader = new InputStreamReader(is);
                StringBuilder builder = new StringBuilder();
                int len = 0;
                char[] chars = new char[1024];
                while ((len = reader.read(chars)) != -1){
                    builder.append(new String(chars,0,len));
                }
                Log.i(TAG, "content:" + builder.toString());
                is.close();
                reader.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值