当前位置:编程学习 > JAVA >>

Java Socket:Java-NIO-ServerSocketChannel

ServerSocketChannel
让我们从最简单的ServerSocketChannel来开始对socket通道类的讨论
ServerSocketChannel是一个基于通道的socket监听器。它同我们所熟悉的java.net.ServerSocket执行相同的基本任务,不过它增加了通道语义,因此能够在非阻塞模式下运行。
用静态的open( )工厂方法创建一个新的ServerSocketChannel对象,将会返回同一个未绑定的java.net.ServerSocket关联的通道。该对等ServerSocket可以通过在返回的ServerSocketChannel上调用socket( )方法来获取。作为ServerSocketChannel的对等体被创建的ServerSocket对象依赖通道实现。这些socket关联的SocketImpl能识别通道。通道不能被封装在随意的socket对象外面。
由于ServerSocketChannel没有bind( )方法,因此有必要取出对等的socket并使用它来绑定到一个端口以开始监听连接。我们也是使用对等ServerSocket的API来根据需要设置其他的socket选项
[java]  
ServerSocketChannel ssc = ServerSocketChannel.open();  
    ServerSocket serverSocket = ssc.socket(); // Listen on port 1234  
    serverSocket.bind(new InetSocketAddress(1234));  
 
同它的对等体java.net.ServerSocket一样,ServerSocketChannel也有accept( )方法。
一旦您创建了一个ServerSocketChannel并用对等socket绑定了它,然后您就可以在其中一个上调用accept( )。
如果您选择在ServerSocket上调用accept( )方法,那么它会同任何其他的ServerSocket表现一样的行为:总是阻塞并返回一个java.net.Socket对象(阻塞的!!!!)
。如果您选择在ServerSocketChannel上调用accept( )方法则会返回SocketChannel类型的对象,返回的对象能够在非阻塞模式下运行。假设系统已经有一个安全管理器(security manager),两种形式的方法调用都执行相同的安全检查。
 
如果以非阻塞模式被调用,当没有传入连接在等待时,ServerSocketChannel.accept( )会立即返回null (因为他是非阻塞的所以要有返回,)。
正是这种检查连接而不阻塞的能力实现了可伸缩性并降低了复杂性。可选择性也因此得到实现。我们可以使用一个选择器实例来注册一个ServerSocketChannel对象以实现新连接到达时自动通知的功能。
演示如何使用一个非阻塞的accept( )方法:
[java] 
package com.anders.selector2;  
  
import java.net.InetSocketAddress;  
import java.net.ServerSocket;  
import java.nio.ByteBuffer;  
import java.nio.channels.ServerSocketChannel;  
import java.nio.channels.SocketChannel;  
  
public class ServerSocketChannelApp {  
    private static final String MSG = "hello, I must be going \n";  
  
    public static void main(String[] args) throws Exception {  
  
        int port = 8989;  
        ServerSocketChannel ssc = ServerSocketChannel.open();  
        ServerSocket ss = ssc.socket();  
        ss.bind(new InetSocketAddress(port));  
        // set no blocking  
        ssc.configureBlocking(false);  
  
        ByteBuffer buffer = ByteBuffer.wrap(MSG.getBytes());  
  
        while (true) {  
            System.out.println("wait for connection ……");  
            SocketChannel sc = ssc.accept();  
              
            if (sc == null) {  
                // no connections, snooze a while ...  
                Thread.sleep(1000);  
            } else {  
                System.out.println("Incoming connection from " + sc.socket().getRemoteSocketAddress());  
                buffer.rewind();  
                //write msg to client  
                sc.write(buffer);  
                sc.close();  
            }  
        }  
    }  
}  
 
ps  阻塞和非阻塞
传统的serversocket阻塞模式:
[java]  
public class ServerSocketApp {  
    public static void main(String[] args) throws Exception {  
        ServerSocket ss = new ServerSocket(8989);  
        ss.accept();  
          
        System.out.println(1);  
    }  
}     
 
运行这个程序 为什么没有输出1 ??? 
 因为ServerSocket  是阻塞模式的 ,什么是阻塞,就是在没有任何连接之前,accept方法一直在那里阻塞着,直到有connection来继续往下执行,所以在运行程序的时候,并没输出1,若要输出  telnet一下就可以了
nio中的 非阻塞:
[java]  
public static void main(String[] args) throws Exception {  
  
        ServerSocketChannel ssc = ServerSocketChannel.open();  
        ServerSocket ss = ssc.socket();  
        ss.bind(new InetSocketAddress(8989));  
        // set no blocking  
        ssc.configureBlocking(false);  
  
        ssc.accept();  
          
        System.out.println(1);  
          
    }  
 
运行这个程序  有1  输出!!
这就是因为  它是非阻塞模式的。
 
SocketChannel
[java]  
public abstract class SocketChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {  
    // This is a partial API listing  
    public static SocketChannel open() throws IOException;  
  
    public static SocketChannel 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类封装点对点、有序的网络连接,类似于我们所熟知并喜爱的TCP/IP网络连接。SocketChannel扮演客户端发起同一个监听服务器的连接。直到连接成功,它才能收到数据并且只会从连接到的地址接收
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,