android-socket-php-Java中的阻塞和非阻塞IO

http://www.cnblogs.com/thinksasa/archive/2013/02/26/2934206.html

http://php.net/manual/zh/function.socket-create.php

http://blog.csdn.net/hguisu/article/details/7448528

上面三个PHP使用socket

 

http://blog.csdn.net/x605940745/article/details/1700164  —-

android之socket编程实例

 

http://www.cnblogs.com/-run/archive/2012/04/07/2434837.html  —-一个类似现在多数聊天软件的冒泡聊天APP

http://www.cnblogs.com/-run/archive/2011/12/29/2306363.html —-Android 基于Socket的聊天室

 

 

 

 

 

 

http://blog.csdn.net/fangchongbory/article/details/7585917 —–

Android 之 Socket通信

http://swerit.iteye.com/blog/1291829  —-php写的服务端和java写的android客户端通过socket通信

http://www.oschina.net/question/570041_152041?sort=time——http://www.workerman.net/

—————————————————————————————————

http://blog.163.com/zhu_xude/blog/static/116769216200962965349372/

http://www.iteye.com/problems/11167

长连接socket:

1概念

Socket:socket实际上是对TCP/IP进行的封装,我们可以使用socket套接字通过socket来传输。首先我们需要明白的一个概念就是通道,简单地说通道就是两个对端可以随时传输数据的信道。我么常说的所谓建立socket连接,也就是建立了客户端与服务器端的通道。

长短连接:显而易见,长连接也就是这个socket连接一直保持连接,也就是通道一直保持通畅,两个对端可以随时发送和接收数据;短连接就是我们发送一次或有限的几次,socket通道就被关闭了。首先,我们必须明白的是socket连接后,如果没有任何一方关闭,这个通道是一直保持着的,换句话说,如果任何一方都不关闭连接,这个socket连接就是长连接,因此Java中的socket本身就是支持长连接的(如一个简单的实验:服务器端不关闭连接,服务器端每隔10秒发送一次数据,服务器端每次都能正确接受数据,这个实验就可以证明)。

那么既然socket本身是支持长连接的,那么为什么我们还要提短连接的概念呢?试想一个中国移动的短信网关(即通过发布socket通信接口)每时每分都有N多个连接发送短信请求,加入服务器不加任何限制地直接和客户端使用长连接那么可想而知服务器需要承受多么大的压力。所以一般的socket服务器端都是会设定超时时间的,也就是timeout,如果超过timeout服务器没有接收到任何数据,那么该服务器就会关闭该连接,从而使得服务器资源得到有效地使用。

2 如何实现长短连接

在1中我们已经介绍了长短连接的概念,服务器如果超过timeout时间接收不到客户端的通信就会断开连接,那么假如客户端在timeout时间前一秒(或者更短的时间)发送一条激活数据来使服务器端重新计时,如此重复就能保证服务器一直不能进入timeout时间,从而一直保持连接,这就是长连接的实现原理。下面我们通过一张图说明:

bubuko.com,布布扣

由上图可见,是否是长连接完全取决于客户端是否会在timeout时间发送心跳消息,因此长短连接是和客户端相关的,服务器端没有任何区别(只不过服务器端需要设定timeout而已)。

代码实现可参照:http://download.csdn.net/detail/feichenwangyalin/7951457

一,如何更好的检测TCP连接是否正常
这方面问题,我上网查了很久,一般来说比较成熟的有两种方法:
1是在应用层制定协议,发心跳包,这也是C#,JAVA等高级语言比较常用的方法。客户端和服务端制定一个通讯协议,每隔一定时间(一般15秒左右),由一方发起,向对方发送协议包;对方收到这个包后,按指定好的通讯协议回一个。若没收到回复,则判断网络出现问题,服务器可及时的断开连接,客户端也可以及时重连。
2通过TCP协议层发送KeepAlive包。这个方法只需设置好你使用的TCP的KeepAlive项就好,其他的操作系统会帮你完成。操作系统会按时发送KeepAlive包,一发现网络异常,马上断开。我就是使用这个方法,也是重点向大家介绍的。

使用第二种方法的好处,是我们在应用层不需自己定协议,通信的两端,只要有一端设好这个值,两边都能及时检测出TCP连接情况。而且这些都是操作系统帮你自动完成的。像我们公司的服务端代码就是早写好的,很难改动。以前也没加入心跳机制,后面要改很麻烦,boss要求检测连接的工作尽量客户端单独完成….
还有一个好处就是节省网络资源。KeepAlive包,只有很简单的一些TCP信息,无论如何也是比你自己设计的心跳包短小的。然后就是它的发送机制,在TCP空闲XXX秒后才开始发送。自己设计心跳机制的话,很难做到这一点。

这种方法也是有些缺陷的。

—————————————————————————————————————

代码:http://gengu.iteye.com/blog/1163702

概念:http://blog.csdn.net/smcwwh/article/details/7186669

在JDK1.4中引入了一个NIO的类库,使得Java涉及IO的操作拥有阻塞式和非阻塞式两种,问一下阻塞IO与非阻塞IO有什么区别?有什么优缺点?

在阻塞模式下,若从网络流中读取不到指定大小的数据量,阻塞IO就在那里阻塞着。比如,已知后面会有10个字节的数据发过来,但是我现在只收到8个字节,那么当前线程就在那傻傻地等到下一个字节的到来,对,就在那等着,啥事也不做,直到把这10个字节读取完,这才将阻塞放开通行。

在非阻塞模式下,若从网络流中读取不到指定大小的数据量,非阻塞IO就立即通行。比如,已知后面会有10个字节的数据发过来,但是我现在只收到8个字节,那么当前线程就读取这8个字节的数据,读完后就立即返回,等另外两个字节再来的时候再去读取。

从上面可以看出,阻塞IO在性能方面是很低下的,如果要使用阻塞IO完成一个Web服务器的话,那么对于每一个请求都必须启用一个线程进行处理。而使用非阻塞IO的话,一到两个线程基本上就够了,因为线程不会产生阻塞,好比一下接收A请求的数据,另一下接收B请求的数据,等等,就是不停地东奔西跑,直接到把数据接收完了。

虽然说,非阻塞IO比阻塞IO有更高的性能,但是对于开发来的,难度就成数倍递增了。

Java中的阻塞和非阻塞IO包各自的优劣思考
NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。
反应器(Reactor):用于事件多路分离和分派的体系结构模式
通常的,对一个文件描述符指定的文件或设备, 有两种工作方式: 阻塞 与非阻塞 。所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止。而对于非阻塞状态, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待 。
一种常用做法是:每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。
另一种较高效的做法是:服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时(读就绪),则调用该socket连接的相应读操作;如果发现某个 Socket端口上有数据可写时(写就绪),则调用该socket连接的相应写操作;如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高。
传统的阻塞式IO,每个连接必须要开一个线程来处理,并且没处理完线程不能退出。
非阻塞式IO,由于基于反应器模式,用于事件多路分离和分派的体系结构模式,所以可以利用线程池来处理。事件来了就处理,处理完了就把线程归还。而传统阻塞方式不能使用线程池来处理,假设当前有10000个连接,非阻塞方式可能用1000个线程的线程池就搞定了,而传统阻塞方式就需要开10000个来处理。如果连接数较多将会出现资源不足的情况。非阻塞的核心优势就在这里。
首先,我们来分析传统阻塞式IO的瓶颈在哪里。在连接数不多的情况下,传统IO编写容易方便使用。但是随着连接数的增多,问题传统IO就不行了。因为前面说过,传统IO处理每个连接都要消耗 一个线程,而程序的效率当线程数不多时是随着线程数的增加而增加,但是到一定的数量之后,是随着线程数的增加而减少。这里我们得出结论,传统阻塞式IO的瓶颈在于不能处理过多的连接。
然后,非阻塞式IO的出现的目的就是为了解决这个瓶颈。而非阻塞式IO是怎么实现的呢?非阻塞IO处理连接的线程数和连接数没有联系,也就是说处理10000个连接非阻塞IO不需要10000个线程,你可以用1000个也可以用2000个线程来处理。因为非阻塞IO处理连接是异步的。当某个连接发送请求到服务器,服务器把这个连接请求当作一个请求"事件",并把这个"事件"分配给相应的函数处理。我们可以把这个处理函数放到线程中去执行,执行完就把线程归还。这样一个线程就可以异步的处理多个事件。而阻塞式IO的线程的大部分时间都浪费在等待请求上了。