Android开发之Socket通信


博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 


在项目开发过程中,不免要与后台进行交互,这时候我们就需要研究一下通信,做一个选择。

Http通信采用UDP,传输过但可能会丢数据,一般我们用来传递字符串或者下载图片时采用,轻量级。

Socket通信采用TCP,安全但慢,一般用来做大型项目中注册、定单信息的传输操作,每个Client都要跟Server 建立连接,所以这个要考虑到用户访问级别,一般百万级,航空公司就是千万级。


下面讲一个TCP与UDP之间的具体差别:


简而言之,TCP与UDP之间的区别在于,TCP传输数据安全但速度慢,UDP传输容易丢包但速度快。一般银行要采取TP协议,IM要使用UDP协议。


首先我们来看一下什么是TCP和UDP。

什么是TCP?

TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified)。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个字节一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

首先,TCP建立连接之后,通信双方都同时可以进行数据的传输,其次,他是全双工的;在保证可靠性上,采用超时重传和捎带确认机制。

在流量控制上,采用滑动窗口协议[1],协议中规定,对于窗口内未经确认的分组需要重传。

在拥塞控制上,采用慢启动算法。

什么是UDP?

UDP 是User Datagram Protocol的简称, 中文名是用户数据包协议,是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。它是IETF RFC 768是UDP的正式规范。在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。 UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。

与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。

UDP协议的主要作用是将网络数据流量压缩成数据报的形式。一个典型的数据报就是一个二进制数据的传输单位。每一个数据报的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

TCP和UDP在android中的使用和在Java里是完全一样的。

首先我们看看TCP连接,下图为TCP连接的一个示意图:

TCP原理TCP传输原理

是不是很好理解,这里就不多说了,直接看代码吧!实践出真知。

TCP服务器端代码:

  1. try {  
  2.             Boolean endFlag = false;  
  3.             ServerSocket ss = new ServerSocket(12345);  
  4.             while (!endFlag) {  
  5.                 // 等待客户端连接  
  6.                 Socket s = ss.accept();  
  7.                 BufferedReader input = new BufferedReader(newInputStreamReader(s.getInputStream()));  
  8.                 //注意第二个参数据为true将会自动flush,否则需要需要手动操作output.flush()  
  9.                 PrintWriter output = newPrintWriter(s.getOutputStream(),true);  
  10.                 String message = input.readLine();  
  11.                 Log.d("Tcp Demo", "message from Client:"+message);  
  12.                 output.println("message received!");  
  13.                 //output.flush();  
  14.                 if("shutDown".equals(message)){  
  15.                     endFlag=true;  
  16.                 }  
  17.                 s.close();  
  18.             }  
  19.             ss.close();  
  20.    
  21.         } catch (UnknownHostException e) {  
  22.             e.printStackTrace();  
  23.         } catch (IOException e) {  
  24.             e.printStackTrace();  
  25.         } 

TCP客户端代码:

  1. try {  
  2.             Socket s = new Socket("localhost", 12345);  
  3.             // outgoing stream redirect to socket  
  4.             OutputStream out = s.getOutputStream();  
  5.             // 注意第二个参数据为true将会自动flush,否则需要需要手动操作out.flush()  
  6.             PrintWriter output = new PrintWriter(out, true);  
  7.             output.println("Hello IdeasAndroid!");  
  8.             BufferedReader input = new BufferedReader(newInputStreamReader(s  
  9.                     .getInputStream()));  
  10.             // read line(s)  
  11.             String message = input.readLine();  
  12.             Log.d("Tcp Demo", "message From Server:" + message);  
  13.             s.close();  
  14.    
  15.         } catch (UnknownHostException e) {  
  16.             e.printStackTrace();  
  17.         } catch (IOException e) {  
  18.             e.printStackTrace();  
  19.         } 

下面我们看看UDP:

UDP传输远离UDP传输原理

UDP服务器端代码:

  1. // UDP服务器监听的端口  
  2.         Integer port = 12345;  
  3.         // 接收的字节大小,客户端发送的数据不能超过这个大小  
  4.         byte[] message = new byte[1024];  
  5.         try {  
  6.             // 建立Socket连接  
  7.             DatagramSocket datagramSocket = new DatagramSocket(port);  
  8.             DatagramPacket datagramPacket = new DatagramPacket(message,  
  9.                     message.length);  
  10.             try {  
  11.                 while (true) {  
  12.                     // 准备接收数据  
  13.                     datagramSocket.receive(datagramPacket);  
  14.                     Log.d("UDP Demo", datagramPacket.getAddress()  
  15.                             .getHostAddress().toString()  
  16.                             + ":" + new String(datagramPacket.getData()));  
  17.                 }  
  18.             } catch (IOException e) {  
  19.                 e.printStackTrace();  
  20.             }  
  21.         } catch (SocketException e) {  
  22.             e.printStackTrace();  
  23.         } 

UDP客户端代码:

  1. public static void send(String message) {  
  2.         message = (message == null ? "Hello IdeasAndroid!" : message);  
  3.         int server_port = 12345;  
  4.         DatagramSocket s = null;  
  5.         try {  
  6.             s = new DatagramSocket();  
  7.         } catch (SocketException e) {  
  8.             e.printStackTrace();  
  9.         }  
  10.         InetAddress local = null;  
  11.         try {  
  12.             // 换成服务器端IP  
  13.             local = InetAddress.getByName("localhost");  
  14.         } catch (UnknownHostException e) {  
  15.             e.printStackTrace();  
  16.         }  
  17.         int msg_length = message.length();  
  18.         byte[] messagemessageByte = message.getBytes();  
  19.         DatagramPacket p = new DatagramPacket(messageByte, msg_length, local,  
  20.                 server_port);  
  21.         try {  
  22.             s.send(p);  
  23.         } catch (IOException e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.     } 
  1. 参考资料51CTO:http://mobile.51cto.com/android-224076.htm

广通软件十多年来耕耘于运维管理软件研发和服务咨询,面向数据中心、互联网、物联网三个领域提供整合化的运维工具和服务。本文作者祝恩良,N次元生物,现任广通软件高级前端开发工程师。今天将以实战角度谈一谈WebSocket的特点与应用。

  WebSocket是一个独立的基于TCP的协议,是HTML5新出的一个协议,跟我们认识的HTTP协议两者之间具有一定的交集,webSocket其实是借助了HTTP这个跳板,档次也杠杠的,能进行全双工通讯(全双工:允许两台设备同时进行双向资料传输)。它和HTTP唯一的关系就是它的握手请求作为一个升级请求(Upgrade request),经由HTTP服务器解析。

  在我们熟知的Http version 1.0 和 version 1.1,升级版本中包含了keep-alive(Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。但是保持链接中,暂停通讯期间不会释放资源,比较浪费服务器资源。)。webSocket其实也囊括了这个概念,虽然实现并不是如此,简单的来说就HTTP协议上的一种补充。

  协议

  在此我们要来讲一个早就存在的概念,持久化的协议,也是webSocket的一个特征,当然这个也是相对于我们的HTTP协议来说的。

  HTTP协议请求:

  HTTP 1.0: 一个request 一个response 一次HTTP链接这样就算是结束了。

HTTP 1.1:在1.0版本有了改进,加入了一个Keep-Alive,在一次HTTP链接中,我可以发送多个request,接收多个response,但是一个request 只能对应一个response。而且这个response,是被动发起的。

  HTTP 1.1:在1.0版本有了改进,加入了一个Keep-Alive,在一次HTTP链接中,我可以发送多个request,接收多个response,但是一个request 只能对应一个response。而且这个response,是被动发起的。

广通软件N次元前端工程师趣谈webSocket

  webSocket是基于HTTP协议,

  小明:报告老师,你明明说是基于TCP协议的来着,真善变。

  老师:别说话,HTTP协议也是基于TCP协议的好不,我这里主要是想表达,webSocket借用了HTTP协议来完成一次握手升级请求,understand?

  GET /chat HTTP/1.1

  Host: xxxx.com

  Upgrade: websocket

  Connection: Upgrade

  Sec-WebSocket-Key: XXXXXX

  Sec-WebSocket-Protocol: XXXX

  Sec-WebSocket-Version: X

  Origin:http://xxxx.com

  以上内容就是一次webSocket的握手升级协议请求。

  有两个参数:

  Upgrade:webSocket

  Connection:Upgrade

  告诉服务器(Ngnix)接线员:attention please!爷发起的是webSocket协议,快帮我找一个对应的客服,不是那个蹩脚的HTTP客服。

  Sec-WebSocket-Key: XXXXX

  Sec-WebSocket-Protocol: A, B

  Sec-WebSocket-Version: X

  首先,Sec-WebSocket-Key 是一个Base64 encode的值,这个是浏览器随机生成的,旨在验证服务器给出的服务是否合格。简单的理解:别忽悠我,我要验证你是不是webSocket客服。

  然后,Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的子协议(客户端支持的子协议列表)。简单理解:我点的服务是这个,别搞错了。

  最后,Sec-WebSocket-Version 是告诉服务器所使用的Websocket版本:服务员,我要的是小学生,不是大学生噢_

  服务员:客官,你的要求,我们都能满足你哟,(^_^)。

  然后服务器会返回下列东西,表示已经接受到请求,成功建立Websocket啦!

  HTTP/1.1101Switching Protocols

  Upgrade: websocket

  Connection: Upgrade

  Sec-WebSocket-Accept: XXXX

  Sec-WebSocket-Protocol: B

  返回的这些内容,就表示服务端升级

  这部分就是HTTP最后负责的内容了,此后跟HTTP毫无关系。上述内容中:

  Upgrade:webSocket

  Connection:Upgrade

  告诉客户端,服务端已经成功升级成webSocket协议了。

  Sec-WebSocket-Accept: XXXX

  这段内容是经过服务确认之后,根据客户端生成Sec-WebSocket-Key生成的值;简单理解,服务端:来,你个死傲娇,给你看我的ID info。

  Sec-WebSocket-Protocol表示服务端从客户端提供的协议列表中,提供自身支持哪个(B)。

  接下去的事,表示跟那个蹩脚的HTTP木有,完全木有,真的木有再有关系了,webSocket客服完全承包后续服务内容。

  WebSocket的作用

  在讲webSocket之前,请允许老夫再BB一会。让我们来脑补一会 long pull 和 ajax轮询吧

  ajax轮询

  ajax的原理非常简单,就是定时器,每隔一会发起一个请求,轮询服务端是否有新的信息。

  场景大致是这样的:

  客户:我的快递到了没呀?(request)

  客服:你好,你是?没有(response)

  客户:我的快递到了没呀?

  客服:你好,你是?没有..

  客户:我的快递到了没呀?

  客服:你好,你是?没有,真没有

  客户:我的快递到了没呀?

  客服:你好,你是?


原文地址:https://www.cnblogs.com/fengju/p/6174504.html