socket通道
来源:互联网 发布:天风证券 数据库新浪 编辑:程序博客网 时间:2024/04/19 01:43
socket通道基础
sokcet通道类可以运行非阻塞模式并且是可选择的。这两个性能可以激活大程序巨大的可伸缩性和灵活性。
所有的socket通道类(DatagramChannel,SocketChannel和ServerSocketChannel)都继承了java.nio.channels.spi.AbstractSelectableChannel。
DatagramChannel和SocketChannel实现定义读和写功能的接口而ServerSocketChannel不实现。ServerSocketChannel负责监听传入的连接和创建新的SocketChannel对象,它本身从不传输数据。全部socket通道类(DatagramChannel、SocketChannel和ServerSocketChannel)在被实例化时都会创建一个对等socket对象。虽然每个socket通道(在java.nio.channels包中)都有一个关联的java.net socket对象,却并非所有的socket都有一个关联的通道。如果您用传统方式(直接实例化)创建了一个Socket对象,它就不会有关SocketChannel并且它的getChannel( )方法将总是返回null。
非阻塞模式
要把一个socket通道置于非阻塞模式,要依靠所有socket通道类的公有超级类:SelectableChannel。
public abstract class SelectableChannel extends AbstractChannel implements Channel { // This is a partial API listing public abstract void configureBlocking (boolean block) throws IOException; public abstract boolean isBlocking( ); public abstract Object blockingLock( ); }
就绪选择(readiness selection)是一种可以用来查询通道的机制,该查询可以判断通道是否准备好执行一个目标操作,如读或写。
设置或重新设置一个通道的阻塞模式:configureBlocking(),传递参数值为true则设为阻塞模式,参数值为false值设为非阻塞模式。用isBlocking( )方法来判断某个socket通道当前处于哪种模式。
blockingLock( )方法:防止socket通道的阻塞模式被更改。只有拥有次对象的锁的线程才能更改通道的阻塞模式。该方法返回锁对象。
Socket socket = null; Object lockObj = serverChannel.blockingLock( ); // have a handle to the lock object, but haven't locked it yet // may block here until lock is acquired synchronize (lockObj) { // This thread now owns the lock; mode can't be changed boolean prevState = serverChannel.isBlocking( ); serverChannel.configureBlocking (false); socket = serverChannel.accept( ); serverChannel.configureBlocking (prevState); }
ServerSocketChannel API
public abstract class ServerSocketChannel extends AbstractSelectableChannel { public static ServerSocketChannel open( ) throws IOException public abstract ServerSocket socket( ); public abstract ServerSocket accept( ) throws IOException; public final int validOps( ) }
ServerSocketChannel是一个基于通道的socket监听器。与java.net.ServerSocket执行相同的基本任务,但增加了通道语义。
open( ):静态工厂方法创建新的的ServerSocketChannel对象,将返回一个未绑定的java.net.ServerSocket关联的通道。对等的ServerSocket通过在返回的ServerSocketChannel对象上调用sockete来获取。
由于ServerSocketChannel没有bind( )方法,因此有必要取出对等的socket并使用它来绑定到一个端口以开始监听连接。
ServerSocketChannel ssc = ServerSocketChannel.open( ); ServerSocket serverSocket = ssc.socket( ); // Listen on port 1234 serverSocket.bind (new InetSocketAddress (1234));ServerSocketChannel也有accept( )方法,如果您选择在ServerSocket上调用accept( )方法,那么它会同任何其他的ServerSocket表现一样的行为:是阻塞并返回一个java.net.Socket对象。如果您选择在ServerSocketChannel上调用accept( )方法则会返回SocketChannel类型的对象,返回的对象能够在非阻塞模式下运行。
SocketChannel
public abstract class SocketChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel { // This is a partial API listing public static SocketChannel open( ) throws IOException public static Sock etChannel open (InetSocketAddress remote) throws IOException public abstract Socket socket( ); public abstract boolean connect (SocketAddress remote) throws IOException; public abstract boolean isConnectionPending( ); public abstract boolean finishConnect( ) throws IOException; public abstract boolean isConnected( ); public final int validOps( ) }
Socket 和SocketChannel 类封装点对点、有序的网络连接。SocketChannel 扮演客户端发起同一个监听服务器的连接,直到连接成功,它才能收到数据并且只会从连接到的地址接收。
每个SocketChannel 对象创建时都是同一个对等的java.net.Socket对象串联的,静态的open( ) 方法可以创建一个新的SocketChannel 对象,而在新创建的SocketChannel 上调用socket( )方法能返回它对等的Socket 对象。
在通道上直接调用connect( )方法或在通道关联的Socket 对象上调用connect( )来将该socket 通道连接。一旦一个socket 通道被连接,它将保持连接状态直到被关闭。在对等Socket 对象上调用connect( )方法,线程在连接建立好或超时过期之前都将保持阻塞。通过在通道上直接调用connect( )方法来建立连接并且通道处于阻塞模式(默认模式),那么连接过程实际上是一样的。
SocketChannel 上并没有一种connect( )方法可以让您指定超时(timeout)值,当connect( )方法在非阻塞模式下被调用时SocketChannel 提供并发连接:它发起对请求地址的连接并且立即返回值。如果返回值是true,说明连接立即建立了(这可能是本地环回连接);如果连接不能立即建立,connect( )方法会返回false 且并发地继续连接建立过程。
假如某个SocketChannel 上当前正由一个并发连接,isConnectPending( )方法就会返回true值,当通道处于中间的连接等待(connectio n-pending)状态时,您只可以调用finishConnect( ) 、isConnectPending( )或isConnected( ) 方法。
InetSocketAddress addr = new InetSocketAddress (host, port); SocketChannel sc = SocketChannel.open( ); sc.configureBlocking (false); sc.connect (addr); while ( ! sc.finishConnect( )) { doSomethingElse( ); } doSomethingWithChannel (sc); sc.close( );
socketChannel是线程安全的,不需要特别的措施来保护发起的多个访问。
socket通道是线程安全的。并发访问时无需特别措施来保护发起访问的多个线程S ocket通道是线程安全的。并发访问时无需特别措施来保护发起访问的多个线程S ocket通道是线程安全的。并发访问时无需特别措施来保护发起访问的多个线程S ocket通道是线程安全的。并发访问时无需特别措施来保护发起访问的多个线程S ocket通道是线程安全的。并发访问时无需特别措施来保护发起访问的多个线程。
sockets是面向流的而非包导向的。它们可以保证发送的字节会按照顺序到达但无法承诺维持字节分组。某个发送器可能给一个socket写入了20个字节而接收器调用read( )方法时却只收到了其中的3个字节。剩下的17 个字节还是传输中。
connect( )和finishConnect( )方法是互相同步的,并且只要其中一个操作正在进行,任何读或写的方法调用都会阻塞。
DatagramChannel
DatagramChannel是模拟包导向的无连接协议(UDP/IP)。
public abstract class DatagramChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel { // This is a partial API listing public static DatagramChannel open( ) throws IOException public abstract DatagramSocket socket( ); public abstract DatagramChannel connect (SocketAddress remote) throws IOException; public abstract boolean isConnected( ); public abstract DatagramChannel disconnect( ) throws IOException; public abstract SocketAddress receive (ByteBuffer dst) throws IOException; public abstract int send (ByteBuffer src, SocketAddress target) public abstract int read (ByteBuffer dst) throws IOException; public abstract long read (ByteBuffer [] dsts) throws IOException; public abstract long read (ByteBuffer [] dsts, int offset, int length) throws IOException; public abstract int write (ByteBuffer src) throws IOException; public abstract long write(ByteBuffer[] srcs) throws IOException; public abstract long write(ByteBuffer[] srcs, int offset, int length) throws IOException; }open()方法创建一个新实例。
socket( ) 方法获取的对等DatagramSocket对象。DatagramChannel对象既可以充当服务器(监听者)也可以充当客户端(发送者)。如果您希望新创建的通道负责监听,那么通道必须首先被绑定到一个端口或地址/端口组合上。绑定DatagramChannel同绑定一个常规的DatagramSocket没什么区别,都是委托对等socket对象上api实现。
DatagramChannel channel = DatagramChannel.open( ); DatagramSocket socket = channel.socket( ); socket.bind (new InetSocketAddress (portNumber));每个数据报(datagram)都是一个自包含的实体,拥有它自己的目的地址以及不依赖其他数据报的数据静荷。
DatagramChannel可以发送单独的数据报给不同的目的地址,同样DatagramChannel也可以接受来自任意地址的数据包,每个到达的数据包都包含它来自何处的信息。
- socket通道
- Socket通道
- Socket通道
- NIO channel Socket通道
- JAVA NIO Socket通道
- NIO - Socket 通道
- socket通道小例子
- io-3-socket通道
- Java nio 之 Socket通道
- Java NIO 4:Socket通道
- Java NIO笔记(七):Socket通道
- android关于连接蓝牙socket 通道
- 通道
- 通道
- 通道
- 通道
- NIO系列(四)——socket通道和serversocket通道
- nio tcp之Socket系列通道 (四)
- 四种类型的人与管理智慧
- 上班族的10大经典哲学
- 工作习惯决定事业成败
- ios系统的图形和描画
- 10大iOS开发者最喜爱的类库
- socket通道
- 让老板看见你在做事
- xcode4 设置调试错误信息小结
- Target runtime Apache Tomcat v7.0 is not defined.
- 阻碍你成功的五个不良习惯
- 高通驱动程序开发参考(一)
- 挖掘大数据的商业价值
- Java基础:数组Array转成List的几种方法
- apache(wamp) 添加python支持