`
dechong
  • 浏览: 16837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java socket 开源框架MINA (一)

阅读更多
nio socket 及其开源框架MINA学习总结(一)

1:传统socket:阻塞式通信

每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。

example:
   

server code:
public class MultiUserServer extends Thread {    
    private Socket client;    
        
    public MultiUserServer(Socket c) {    
        this.client = c;    
    }    
   
    public void run() {    
        try {    
            BufferedReader in = new BufferedReader(new InputStreamReader(client    
                    .getInputStream()));    
            PrintWriter out = new PrintWriter(client.getOutputStream());    
            // Mutil User but can't parallel    
            while (true) {    
                String str = in.readLine();    
                System.out.println(str);    
                SocketLog.debug("receive message: " + str);    
                out.println("has receive....");    
                out.flush();    
                if (str.equals("end"))    
                    break;    
            }    
            client.close();    
        } catch (IOException ex) {    
        }     
    }    
   
    public static void main(String[] args) throws IOException {    
        int port = 5678;    
        if (args.length > 0)    
            port = Integer.parseInt(args[0]);    
        ServerSocket server = new ServerSocket(port);    
        SocketLog.debug("the server socket application is created!");    
        while (true) {    
            // transfer location change Single User or Multi User    
            MultiUserServer mu = new MultiUserServer(server.accept());    
            mu.start();    
        }    
    }    
}   
client code:

public class Client {    
   
    static Socket server;    
   
    public static void main(String[] args) throws Exception {    
            
        //set socket proxy.    
        String proxyHost = "192.16.24.12";    
        String proxyPort = "1080";    
        System.getProperties().put("socksProxySet","true");    
        System.getProperties().put("socksProxyHost",proxyHost);    
        System.getProperties().put("socksProxyPort",proxyPort);     
            
        String host = "12.201.29.10";    
        int port = 10086;    
        if (args.length > 1)    
        {    
            host = args[0];    
            port = Integer.parseInt(args[1]);    
        }    
        System.out.println("connetioning:" + host + ":" + port);    
        server = new Socket(host, port);    
        BufferedReader in = new BufferedReader(new InputStreamReader(server    
                .getInputStream()));    
        PrintWriter out = new PrintWriter(server.getOutputStream());    
        BufferedReader wt = new BufferedReader(new InputStreamReader(System.in));    
        while (true) {    
            String str = wt.readLine();    
            out.println(str);    
            out.flush();    
            if (str.equals("end")) {    
                break;    
            }    
            System.out.println(in.readLine());    
        }    
        server.close();    
    }    
}   


2.nio:非阻塞通讯模式

2.1NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。
反应器模式的核心功能如下:
将事件多路分用
将事件分派到各自相应的事件处理程序

NIO 的非阻塞 I/O 机制是围绕 选择器和 通道构建的。Channel 类表示服务器和客户机之间的一种通信机制。Selector 类是 Channel 的多路复用器。 Selector 类将传入客户机请求多路分用并将它们分派到各自的请求处理程序。
通道(Channel 类):表示服务器和客户机之间的一种通信机制。
选择器(Selector类):是 Channel 的多路复用器。

Selector 类将传入的客户机请求多路分用并将它们分派到各自的请求处理程序。简单的来说:NIO是一个基于事件的IO架构,最基本的思想就是:有事件我通知你,你再去做你的事情.而且NIO的主线程只有一个,不像传统的模型,需要多个线程以应对客户端请求,也减轻了JVM的工作量。
当Channel注册至Selector以后,经典的调用方法如下:       nio中取得事件通知,就是在selector的select事件中完成的。在selector事件时有一个线程向操作系统询问,selector中注册的Channel&&SelectionKey的键值对的各种事件是否有发生,如果有则添加到selector的selectedKeys属性Set中去,并返回本次有多少个感兴趣的事情发生。如果发现这个值>0,表示有事件发生,马上迭代selectedKeys中的SelectionKey,
根据Key中的表示的事件,来做相应的处理。实际上,这段说明表明了异步socket的核心,即异步socket不过是将多个socket的调度(或者还有他们的线程调度)全部交给操作系统自己去完成,异步的核心Selector,不过是将这些调度收集、分发而已。

 
while (somecondition) {    
    int n = selector.select(TIMEOUT);    
    if (n == 0)    
        continue;    
    for (Iterator iter = selector.selectedKeys().iterator(); iter    
            .hasNext();) {    
        if (key.isAcceptable())    
            doAcceptable(key);    
        if (key.isConnectable())    
            doConnectable(key);    
        if (key.isValid() && key.isReadable())    
            doReadable(key);    
        if (key.isValid() && key.isWritable())    
            doWritable(key);    
        iter.remove();    
    }    
}  


2.2 nio example:
server code:

  
public class NonBlockingServer    
{    
    public Selector sel = null;    
    public ServerSocketChannel server = null;    
    public SocketChannel socket = null;    
    public int port = 4900;    
    String result = null;    
   
   
    public NonBlockingServer()    
    {    
        System.out.println("Inside default ctor");    
    }    
        
    public NonBlockingServer(int port)    
    {    
        System.out.println("Inside the other ctor");    
        this.port = port;    
    }    
   
    public void initializeOperations() throws IOException,UnknownHostException    
    {    
        System.out.println("Inside initialization");    
        sel = Selector.open();    
        server = ServerSocketChannel.open();    
        server.configureBlocking(false);    
        InetAddress ia = InetAddress.getLocalHost();    
        InetSocketAddress isa = new InetSocketAddress(ia,port);    
        server.socket().bind(isa);    
    }    
        
    public void startServer() throws IOException    
    {    
        System.out.println("Inside startserver");    
        initializeOperations();    
        System.out.println("Abt to block on select()");    
        SelectionKey acceptKey = server.register(sel, SelectionKey.OP_ACCEPT );     
        
        while (acceptKey.selector().select() > 0 )    
        {       
            
            Set readyKeys = sel.selectedKeys();    
            Iterator it = readyKeys.iterator();    
   
            while (it.hasNext()) {    
                SelectionKey key = (SelectionKey)it.next();    
                it.remove();    
                    
                if (key.isAcceptable()) {    
                    System.out.println("Key is Acceptable");    
                    ServerSocketChannel ssc = (ServerSocketChannel) key.channel();    
                    socket = (SocketChannel) ssc.accept();    
                    socket.configureBlocking(false);    
                    SelectionKey another = socket.register(sel,SelectionKey.OP_READ|SelectionKey.OP_WRITE);    
                }    
                if (key.isReadable()) {    
                    System.out.println("Key is readable");    
                    String ret = readMessage(key);    
                    if (ret.length() > 0) {    
                        writeMessage(socket,ret);    
                    }    
                }    
                if (key.isWritable()) {    
                    System.out.println("THe key is writable");    
                    String ret = readMessage(key);    
                    socket = (SocketChannel)key.channel();    
                    if (result.length() > 0 ) {    
                        writeMessage(socket,ret);    
                    }    
                }    
            }    
        }    
    }    
   
    public void writeMessage(SocketChannel socket,String ret)    
    {    
        System.out.println("Inside the loop");    
   
        if (ret.equals("quit") || ret.equals("shutdown")) {    
            return;    
        }    
        try   
        {    
   
            String s = "This is context from server!-----------------------------------------";    
            Charset set = Charset.forName("us-ascii");    
            CharsetDecoder dec = set.newDecoder();    
            CharBuffer charBuf = dec.decode(ByteBuffer.wrap(s.getBytes()));    
            System.out.println(charBuf.toString());    
            int nBytes = socket.write(ByteBuffer.wrap((charBuf.toString()).getBytes()));    
            System.out.println("nBytes = "+nBytes);    
                result = null;    
        }    
        catch(Exception e)    
        {    
            e.printStackTrace();    
        }    
   
    }    
      
    public String readMessage(SelectionKey key)    
    {    
        int nBytes = 0;    
        socket = (SocketChannel)key.channel();    
        ByteBuffer buf = ByteBuffer.allocate(1024);    
        try   
        {    
            nBytes = socket.read(buf);    
            buf.flip();    
            Charset charset = Charset.forName("us-ascii");    
            CharsetDecoder decoder = charset.newDecoder();    
            CharBuffer charBuffer = decoder.decode(buf);    
            result = charBuffer.toString();    
            
        }    
        catch(IOException e)    
        {    
            e.printStackTrace();    
        }    
        return result;    
    }    
   
    public static void main(String args[])    
    {    
        NonBlockingServer nb;    
        if (args.length < 1)    
        {    
            nb = new NonBlockingServer();    
        }    
        else   
        {    
            int port = Integer.parseInt(args[0]);    
            nb = new NonBlockingServer(port);    
        }    
             
        try   
        {    
            nb.startServer();    
            System.out.println("the nonBlocking server is started!");    
        }    
        catch (IOException e)    
        {    
            e.printStackTrace();    
            System.exit(-1);    
        }    
            
    }    
}   
client code:

public class Client {    
    public SocketChannel client = null;    
   
    public InetSocketAddress isa = null;    
   
    public RecvThread rt = null;    
   
    private String host;    
   
    private int port;    
   
    public Client(String host, int port) {    
        this.host = host;    
        this.port = port;    
    }    
   
    public void makeConnection() {    
        String proxyHost = "192.168.24.22";    
        String proxyPort = "1080";    
        System.getProperties().put("socksProxySet", "true");    
        System.getProperties().put("socksProxyHost", proxyHost);    
        System.getProperties().put("socksProxyPort", proxyPort);    
   
        int result = 0;    
        try {    
            client = SocketChannel.open();    
            isa = new InetSocketAddress(host, port);    
            client.connect(isa);    
            client.configureBlocking(false);    
            receiveMessage();    
        } catch (UnknownHostException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        }    
        long begin = System.currentTimeMillis();    
   
        sendMessage();    
   
        long end = System.currentTimeMillis();    
        long userTime = end - begin;    
        System.out.println("use tiem: " + userTime);    
        try {    
            interruptThread();    
            client.close();    
            System.exit(0);    
        } catch (IOException e) {    
            e.printStackTrace();    
        }    
    }    
   
    public int sendMessage() {    
                System.out.println("Inside SendMessage");    
        String msg = null;    
        ByteBuffer bytebuf;    
        int nBytes = 0;    
        try {    
            msg = "It's message from client!";    
            System.out.println("msg is "+msg);    
            bytebuf = ByteBuffer.wrap(msg.getBytes());    
            for (int i = 0; i < 1000; i++) {    
                nBytes = client.write(bytebuf);    
                System.out.println(i + " finished");    
            }    
            interruptThread();    
            try {    
                Thread.sleep(5000);    
            } catch (Exception e) {    
                e.printStackTrace();    
            }    
            client.close();    
            return -1;    
   
        } catch (IOException e) {    
            e.printStackTrace();    
        }    
   
        return nBytes;    
   
    }    
   
    public void receiveMessage() {    
        rt = new RecvThread("Receive THread", client);    
        rt.start();    
   
    }    
   
    public void interruptThread() {    
        rt.val = false;    
    }    
   
    public static void main(String args[]) {    
        if (args.length < 2) {    
            System.err.println("You should put 2 args: host,port");    
        } else {    
            String host = args[0];    
            int port = Integer.parseInt(args[1]);    
            Client cl = new Client(host, port);    
            cl.makeConnection();    
        }    
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));    
        String msg;    
   
    }    
   
    public class RecvThread extends Thread {    
        public SocketChannel sc = null;    
   
        public boolean val = true;    
   
        public RecvThread(String str, SocketChannel client) {    
            super(str);    
            sc = client;    
        }    
   
        public void run() {    
            int nBytes = 0;    
            ByteBuffer buf = ByteBuffer.allocate(2048);    
            try {    
                while (val) {    
                    while ((nBytes = nBytes = client.read(buf)) > 0) {    
                        buf.flip();    
                        Charset charset = Charset.forName("us-ascii");    
                        CharsetDecoder decoder = charset.newDecoder();    
                        CharBuffer charBuffer = decoder.decode(buf);    
                        String result = charBuffer.toString();    
                        System.out.println("the server return: " + result);    
                        buf.flip();    
   
                    }    
                }    
   
            } catch (IOException e) {    
                e.printStackTrace();    
   
            }
 

分享到:
评论
1 楼 maozilee 2011-08-22  
NIO开发对于很少开发c/s架构的人来说 太困难了,,所以mina出现了!

相关推荐

    Android Java Socket框架 Mina2.0

    总之,Android Java Socket框架Mina2.0提供了一个强大的工具集,使得开发者能够更专注于业务逻辑,而无需过多关注底层的网络通信细节。通过理解和掌握Mina,开发者可以构建出高效、稳定、易于扩展的网络应用。

    niosocket及其开源框架MINA学习总结收集.pdf

    MINA (Java Multithreaded Network Application Framework) 是一个基于NIO的开源框架,它为开发高性能、高可用性的网络应用提供了抽象层。MINA 提供了事件驱动的模型,简化了网络编程的复杂性,开发者可以通过编写...

    Mina+Socket通信

    Mina和Socket是两种常见的网络通信框架和技术,它们在Java编程环境中被广泛使用。本篇文章将深入探讨如何使用Mina与Socket实现通信,并提供客户端和服务端的实现代码概述。 Mina(全称“MINA: Minimalistic ...

    一般Socket客户端与Mina NIO Socket客户端对比示例

    相比之下,Mina NIO是一种基于Java NIO API的网络通信框架,它利用了多路复用器(Selector)和通道(Channel)的概念,实现了非阻塞I/O。在Mina中,`SocketConnectorSupport.java`可能是一个自定义的连接器支持类,...

    mina框架中socket应用的简单小项目,包含了所需jar

    "mina框架" 标签强调了项目的核心技术是Apache MINA,一个用于构建网络应用程序的开源框架。"socket" 标签则表明项目涉及到的是网络通信的基础部分,即Socket编程,这是互联网应用中常用的数据交换机制。 **文件...

    基于Android开发MINA框架使用详解

    此时,我们可以借助开源框架MINA(Multi-purpose Infrastructure for Network Applications)来构建高效、可扩展的网络应用程序。MINA是一个用Java编写的高性能、异步I/O框架,适用于多种传输协议,如TCP/IP和UDP/IP...

    java socket nio 研究

    2. `MinaTimeServer.java`:Mina是一个开源的Java网络应用框架,它提供了一套高度可扩展的、高效的网络通信API。这个类可能是使用Mina库来实现的NIO时间服务器,Mina简化了NIO的使用,提供了更高级别的抽象。 3. `...

    mina框架的demo 入门,开发

    Mina框架是一个基于Java的网络通信应用框架,它为高性能、高可用性的网络应用程序提供了强大的支持。本教程将深入探讨Mina框架的入门与开发,帮助你快速掌握这个框架的关键概念和技术。 首先,理解Mina的核心概念至...

    mina连接 mina心跳连接 mina断线重连

    Apache Mina是一个开源的网络通信框架,常用于构建高性能、高效率的服务端应用程序,尤其在Java平台上。在本文中,我们将深入探讨Mina的核心概念,包括连接管理、心跳机制以及断线重连策略。 首先,让我们理解"Mina...

    socket框架调研文档

    Apache MINA是另一个用于开发高性能网络应用的框架,它基于Java NIO技术,支持TCP、UDP和串口通信,设计目标是提供高可用性和易用性。MINA与Netty一样,由Trustin Lee创建,但MINA的架构可能使得某些不必要的特性...

    MinaServer for Android

    Mina是一个开源项目,旨在简化网络应用开发,尤其适用于TCP/IP和UDP/IP协议,如Socket编程。通过使用Mina,开发者可以构建复杂的服务端系统,如FTP服务器、聊天服务器或者任何需要处理大量并发连接的应用。 **...

    MINA2 教程 socket

    MINA2,全称为“Java Multicast Network Application Framework 2”,是Apache软件基金会的一个开源项目,主要用于构建高性能、高可用性的网络应用程序。MINA提供了一种抽象层,简化了网络编程,尤其是TCP/IP和UDP/...

    mina socket 代码

    MinA Socket是Apache软件基金会下的一个开源项目,全称为“MINA (Multi-purpose Infrastructure for Network Applications)”,它提供了一个高性能、可伸缩的网络应用程序框架,用于开发基于TCP/IP和UDP/IP协议的...

    一个应用mina的实例(源码)

    Apache Mina是一个开源项目,它提供了一个高度可扩展和高性能的网络通信框架。这个实例是基于Mina框架构建的一个应用程序,名为"BTUSimulator",它可能是用来模拟某种网络通信或者服务的。让我们深入探讨一下Mina...

    mina 多路分离解码

    mina框架是Apache软件基金会的一个开源项目,它为Java开发者提供了一套高效、功能丰富的网络通信库,主要用于构建高性能的网络应用服务器,如TCP和UDP服务。在mina框架中,“多路分离解码”(Multiplexing Decoding...

    java 网络框架

    QuickServer是一个开源的Java TCP服务器框架,提供了一种简单的方式来构建网络应用。通过学习和研究这些示例,开发者可以快速理解如何利用该框架构建自己的网络服务。 总结起来,Java网络框架结合TCP和UDP协议,多...

    一个经典的socket通信程序

    4. **mina-1.1.5**:Mina是一个开源项目,提供了高度可扩展的网络应用框架,它简化了Java的网络编程,特别是对于TCP和UDP协议。Mina库提供了高级API来处理I/O操作,使得开发者可以专注于业务逻辑而不是底层网络细节...

    apache mina实例免费下载

    Apache MINA(Multipurpose Infrastructure for Network Applications)是一个开源框架,主要设计用于简化网络应用程序的开发,尤其是基于TCP和UDP协议的应用。它提供了高度可扩展和高性能的非阻塞I/O模型,使得...

    mina源代码学习提供下载

    Apache MINA(Multipurpose Infrastructure for Network Applications)是一个Java框架,专为开发高性能和高度可扩展的网络应用程序而设计。MINA 提供了一种抽象层,允许开发者远离底层的Socket编程,专注于业务逻辑...

    mina简单示例

    Apache Mina是一个开源的网络通信应用框架,主要应用于Java平台。它为高性能、高可用性和伸缩性提供了基础,使得开发者能够轻松构建网络应用程序,如TCP/IP和UDP协议的服务器和客户端。Mina的核心思想是将网络编程...

Global site tag (gtag.js) - Google Analytics