Android技能树 — 网络小结(4)之socket/websocket/webservice

前言

介于自己的网络方面知识烂的一塌糊涂,所以准备写相关网络的文章,但是考虑全部写在一篇太长了,所以分开写,希望大家能仔细看,最好可以指出我的错误,让我也能纠正。

1.讲解相关的整个网络体系结构:

Android技能树 — 网络小结(1)之网络体系结构

2.讲解相关网络的重要知识点,比如很多人都听过相关网络方面的名词,但是仅限于听过而已,什么tcp ,udp ,socket ,websocket, http ,https ,然后webservice是啥,跟websocket很像,socket和websocket啥关系长的也很像,session,token,cookie又是啥。

Android技能树 — 网络小结(2)之TCP/UDP

Android技能树 — 网络小结(3)之HTTP/HTTPS

Android技能树 — 网络小结(4)之socket/websocket/webservice

相关网络知识点小结- cookie/session/token(待写)

3.相关的第三方框架的源码解析,毕竟现在面试个大点的公司,okhttp和retrofit源码是必问的。

Android技能树 — 网络小结(6)之 OkHttp超超超超超超超详细解析

Android技能树 — 网络小结(7)之 Retrofit源码详细解析

正文

1. Socket

我们在网络体系结构小结中提过,TCP/IP的体系结构图为

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

在传输层中为TCP和UDP,解决了数据之间的运输,但是我们很少直接去调用TCP和UDP,比如我们现在是要用TCP传输数据,你要写代码去进行TCP的三次握手连接和四次挥手断开等,而且可能还要考虑什么滑动窗口,累积确认、分组缓存、流量控制等?所以我们正需要某个类,这个类帮我们封装好了TCP的连接,传输,断开等一系列相关各类操作,是不是就很方便了。没错,这个类就是Socket。

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

Socket 即套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)

1.Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)
2.即:通过Socket,我们才能在Andorid平台上通过 TCP/IP协议进行开发
3.对用户来说,只需调用Socket去组织数据,以符合指定的协议,即可通信

关于Socket的使用,代码一搜一大把,这里我就快速通过,直接讲一下大致代码流程,我们知道现在是为了把一个信息从一台设备到另外一台设备,在网络体系结构小结中提过IP是用来确定信息最后到哪个目标设备,所以我们一定要知道IP,到了目标设备后,目标设备可能开启了很多应用程序(多个进程),这时候怎么知道这个数据包到哪个进程呢,这里也会涉及到端口,我们平常写代码,有时候是不是会说某个端口被占用了。所以我们同时除了ip还要知道端口

所以初步是设备A的ip设备A的端口,设备B的ip,设备B的端口,换成我们平常的通俗说法就是客户端ip客户端端口,服务端ip,服务端端口,外加上我们的Socket用来操作TCP,同时也可以操作 UDP,所以同时还有一个协议。所以最终涉及到这5个元素,socket 通过这5个元素来确定。

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

具体的Socket代码就不多说了:

客户端:

public class ClientSocket {
 public static void main(String args[]) {
    String host = "127.0.0.1";
    int port = 8919;
    try {
     Socket client = new Socket(host, port);
     Writer writer = new OutputStreamWriter(client.getOutputStream());
     writer.write("Hello From Client");
     writer.flush();
     writer.close();
     client.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
  }
 
}
复制代码

服务端:

public class Server {
  public static void main(String args[]) {
  
    ServerSocket echoServer = null;
    String line;
    DataInputStream is;
    PrintStream os;
    Socket clientSocket = null;
    
    try {
      echoServer = new ServerSocket(9999);
    }
    catch (IOException e) {
      System.out.println(e);
    }
   
    try {
        clientSocket = echoServer.accept();
        is = new DataInputStream(clientSocket.getInputStream());
        os = new PrintStream(clientSocket.getOutputStream());
        // As long as we receive data, echo that data back to the client.
        while (true) {
         line = is.readLine();
         os.println(line);
        }
    } catch (IOException e) {
        System.out.println(e);
      }
    }
}
复制代码

看了代码,我们发现Socket的一个很大的特点就是服务端和客户端可以相互传数据。这和我们平时的网络交互差别挺大的,毕竟我们平常访问后台接口,很少说后台突然通过这个接口发个数据给客户端是吧,一般都是客户端主动发送接口请求,然后才能拿到相关数据。

2. WebSocket

我们在上面的Socket的相关介绍可以看到,Socket是在运输层做了一层抽象层,是TCP/UDP 的 api工具类,所以Socket不算是应用层类,而我们在相关网络知识点小结- http/https提过Http/Https是属于应用层的,而我们的WebSocket也是属于应用层的。所以说WebSocket和Http/Https是同一层级的。

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

而我们也经常看到很多所谓的Http与WebSocket的区别文章等,比如:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

而我们在上面介绍Socket的时候提过,Socket可以双向通信,所以WebSocket也是可以双向通信的,而在没有双向通信的时候,用Http来进行双向通信更多的是使用长轮询。

在WebSocket API尚未被众多浏览器实现和发布的时期,开发者在开发需要接收来自服务器的实时通知应用程序时,不得不求助于一些“hacks”来模拟实时连接以实现实时通信,最流行的一种方式是长轮询。长轮询主要是发出一个HTTP请求到服务器,然后保持连接打开以允许服务器在稍后的时间响应(由服务器确定)。为了这个连接有效地工作,许多技术需要被用于确保消息不错过,如需要在服务器端缓存和记录多个的连接信息(每个客户)。虽然长轮询是可以解决这一问题的,但它会耗费更多的资源,如CPU、内存和带宽等,要想很好的解决实时通信问题就需要设计和发布一种新的协议。 WebSocket 是伴随HTML5发布的一种新协议。它实现了浏览器与服务器全双工通信(full-duplex),可以传输基于消息的文本和二进制数据

WebSocket和长轮询之间的带宽消耗差异:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

而WebSocket连接的时候,也会用到http,因为在最刚开始发出连接请求的时候,也是要借助于现有的HTTP协议,当连接成功后,其他时候直接基于TCP完成通信。

1.首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
2.然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
3.最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

当然如果只是了解大概的WebSocket和Http的区别,可以看这篇:WebSocket的原理,以及和Http的关系,用了通俗易懂的例子说明了,更加好记,但是并没有说明具体的详细内容。

详细的可以看看这篇: 【腾云阁】WebSocket 浅析

那我们既然是安卓开发,那我们怎么样使用WebSocket呢,我想现在很多人都应该网络请求这块使用的是Okhttp吧,虽然我们平时就是用Okhttp做简单的http/https请求,但其实它也是支持WebSocket的,具体大家可以直接搜索相关文章

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

3. WebService

首先如果有人做过相关的 WebService 的话,就会觉得大体上其实和平常的 http 请求差不多,都是发送一个请求,然后接受相应的返回数据,可能最直观的差别是平常我们用 http 发送请求,接收到请求/响应报文中的请求体都是 JSON,而WebService用的是 XML 的形式。其实的确是这样,因为Webservice就是采用了基于http的soap协议传输数据,所以简单理解为soap=http+xml。因为用了xml之后,更加的通用性,对于跨平台跨应用来说都更好的相互通信解析。

XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术。

我们具体一项项来查看:

3.1 XML+XSD

WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的 返回结果是什么)。XML是WebService平台中表示数据的格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关 的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。

XSD又是什么呢,因为我们平常写xml格式的内容,可以随便写,只要符合基本的xml格式就行,但实际上这样就没有一套标准的数据类型了。所以XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

3.2 SOAP

WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明 HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC方法来调用Web Service。

所以 SOAP协议 = HTTP协议 + XML数据格式

3.3 WSDL

使用过WebService应该都知道这个,WebService务器端首先要通过一个WSDL文件来说明有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受 的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。

比如下面这个是国内手机号码归属地查询WEB服务:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

而且提供了soap1.1/soap1.2/get/post 四种方式来调用获取:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》
《Android技能树 — 网络小结(4)之socket/websocket/webservice》
《Android技能树 — 网络小结(4)之socket/websocket/webservice》

但是实际上可能没有写的这么详细,就是给我们一个WSDL,里面的内容是这样的:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

这里有些人可能不知道怎么来读懂这个文件,其实很简单,我们一步步来看:

  1. 我们先找到相应的service:

    《Android技能树 — 网络小结(4)之socket/websocket/webservice》 我们可以看到里面有soap1.1,soap1.2, http-get,http-post四种,我们以soap1.2为例,我们可以看到她后面binding = "tns:MobileCodeWSSoap12",所以我们查找相应的binding的值

  2. 我们搜索到了MobileCodeWSSoap12后发现是:

    《Android技能树 — 网络小结(4)之socket/websocket/webservice》 所以我们要继续跟踪下去,这下查找的是type="tns:MobileCodeWSSoap"

  3. 我们搜索关键字:tns:MobileCodeWSSoap后发现的是:

    《Android技能树 — 网络小结(4)之socket/websocket/webservice》 我们可以看到<wsdl:operation name="getMobileCodeInfo">,所以我们知道方法名字叫getMobileCodeInfo,同时下面有 <wsdl:input message="tns:getMobileCodeInfoSoapIn"/> 和 <wsdl:output message="tns:getMobileCodeInfoSoapOut"/> 看字面意思就知道是输入参数和输出参数,然后继续对应关键字getMobileCodeInfoSoapIngetMobileCodeInfoSoapOut搜下

  4. 搜到的结果为:

    《Android技能树 — 网络小结(4)之socket/websocket/webservice》 ,然后继续跟踪getMobileCodeInfogetMobileCodeInfoResponse

  5. 最终看到了具体的输入参数和输出参数。

    《Android技能树 — 网络小结(4)之socket/websocket/webservice》 明显输入参数是mobileCode和userID,输出参数是getMobileCodeInfoResult,而且都是字符串类型。

总体来说就是 <service> -> <binding> -> <type> -> <message> -> <element>

那么另外一个问题来了,我们从哪里得到WSDL呢?

WSDL 文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。比如上面我贴图的WSDL内容就是只要访问:ws.webxml.com.cn/WebServices…就可以了。

WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

补充1 :可能有些人会说WSDL的内容还是看不懂,可以参考 WSDL 教程WebService中的WSDL详细解析 学习。

《Android技能树 — 网络小结(4)之socket/websocket/webservice》

补充2 : 刚提到了Soap1.1 和 Soap1.2:

《Android技能树 — 网络小结(4)之socket/websocket/webservice》
《Android技能树 — 网络小结(4)之socket/websocket/webservice》
《Android技能树 — 网络小结(4)之socket/websocket/webservice》

结语:

emmmm…….轻喷即可。有错请留言,我可以进行修改。其中文章配图部分引自下面参考文章。

参考文章:

张大胖的socket

Android:这是一份很详细的Socket使用攻略

WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)

【腾云阁】WebSocket 浅析

WebService学习总结(一)——WebService的相关概念

WebService基础学习(一)—基础知识

WebService中的WSDL详细解析

WebService就是这么简单

WebService中的WSDL详细解析

    原文作者:HTTP
    原文地址: https://juejin.im/post/5b702932e51d4566747de0c7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞