千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0
早就听说JAVA的NIO比IO牛一些,可是牛在哪里一直都不知道,并且NIO比IO难学,搞了半天终于用NIO弄了两个程序,一个是服务器端,一个是客户端,都是用NIO连接的,代码如下,注释比较少,输出比较多:)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 
*/
package testnio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

/**
 *
 * 
@author hadeslee
 
*/
public class Receive {

    
public static void main(String[] args) throws Exception {
        
boolean b = true;
        ByteBuffer buffer 
= ByteBuffer.allocate(1024);
        ServerSocketChannel ss 
= ServerSocketChannel.open();
        ss.socket().bind(
new InetSocketAddress(8888));
        ss.configureBlocking(
false);
        Selector se 
= Selector.open();
        ss.register(se, SelectionKey.OP_ACCEPT);
        
while (se.select() > 0) {
            Set
<SelectionKey> set = se.selectedKeys();
            System.out.println(
"进入一个循环,大小是:" + set.size());
            
for (SelectionKey key : set) {
                
int ops = key.readyOps();
                System.out.println(
"ops=" + ops);
                
if ((ops & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
                    SocketChannel sc 
= ss.accept();
                    System.err.println(
"有新的连接了" + sc);
                    System.err.println(
"地址是:" + sc.socket());
                    sc.configureBlocking(
false);
                    sc.register(se, SelectionKey.OP_READ);
                }
                
if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                    System.err.println(
"有新的读取");
                    SocketChannel sc 
= (SocketChannel) key.channel();
                    System.out.println(sc.isConnected());
                    sc.read(buffer);
                    buffer.flip();
                    
//System.out.println(new String(buffer.array()));
                    Thread.sleep(5000);
                    
if (b) {
                        b 
= false;
                        sc.write(buffer);
                    }

                }
            }
            set.clear();
            System.out.println(
"退出循环");
        }

    }
}

客户端:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 
*/
package testnio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;

/**
 *
 * 
@author hadeslee
 
*/
public class Send {

    
public static void main(String[] args) throws Exception {
        SocketChannel sc 
= SocketChannel.open();
        ByteBuffer buffer 
= ByteBuffer.allocate(1024);
        Selector se 
= Selector.open();
        buffer.put(
"我是中国人,我爱我的祖国,hadeslee".getBytes());
        buffer.flip();
        
        sc.configureBlocking(
false);
        sc.register(se, SelectionKey.OP_CONNECT 
| SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        sc.connect(
new InetSocketAddress("192.168.1.58"8888));
        
while(!sc.finishConnect());
        sc.write(buffer);
        System.out.println(
"进入循环");
        Thread.sleep(
10000);
        
int sum = se.select();
        
while (se.select() > 0) {
            Thread.sleep(
100);
               
                System.out.println(
"终于大于0了");
                Set
<SelectionKey> set = se.selectedKeys();
                System.out.println(
"大小是:"+set.size());
                
for (SelectionKey key : set) {
                    
int ops = key.readyOps();
                    
if ((ops & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT) {
                        sc.write(buffer);
                        System.out.println(
"连接成功");
                    }
                    
if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                        System.out.println(
" 收到东西");
                        sc.read(buffer);
                        buffer.flip();
                        System.out.println(
"收到的是:" + new String(buffer.array(),0,buffer.limit()));
                        sc.write(buffer);
                    }
                }
               se.selectedKeys().clear();
        }
    }

    
private static ByteBuffer[] get(String heads) {
        ByteBuffer[] bbs 
= new ByteBuffer[heads.length];
        
for (int i = 0; i < bbs.length; i++) {
            String s 
= heads[i];
            bbs[i] 
= ByteBuffer.allocateDirect(1024);
            bbs[i].put(s.getBytes());
            bbs[i].flip();
        }
        
return bbs;
    }
}
有机会再好好研究它们之间的更加具体的用法,以上的只是一个简单的,能互连的一个例子.




尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2007-11-05 10:50 千里冰封 阅读(16751) 评论(8)  编辑  收藏 所属分类: JAVASE

FeedBack:
# re: NIO连接socket
2007-11-05 11:48 | Michael Zheng
没看代码 :) 就是看到了NIO IO就进来看看 哈哈啊

据Thinking In Java 说,Java 中的IO用NIO重写过了

所以效率差别不大 :)

大家讨论讨论啊  回复  更多评论
  
# re: NIO连接socket
2007-11-05 13:18 | 诗特林
java5里的NIO我觉得比IO还是改进比较大的.不信去运行一下Thinking in Java 4th版里的相关例子.我试过,要快些,当然,NIO做了不少扩展,  回复  更多评论
  
# re: NIO连接socket
2008-04-05 16:44 | fenixshadow
Apache Mina是一个NIO框架,用来实现socket服务端非常方便。

用他们的广告语来说就是:

Convert ByteBuffer to String for free!


不过实现客户端有点麻烦。  回复  更多评论
  
# re: NIO连接socket
2008-07-07 16:04 | 冰河の泥鱼
哈哈,你写的代码,在我这里编译不通过。我使用的是JDK1.6+eclipse3.3.2,老大是不是应该测试后再发上来呢?  回复  更多评论
  
# re: NIO连接socket[未登录]
2008-07-07 17:34 | 小小
@冰河の泥鱼
哪里编译通不过,提示第几行?
我这里都可以编译通过的啊.  回复  更多评论
  
# re: NIO连接socket
2008-07-08 11:18 | 冰河の泥鱼
@小小
一,简单的错误:
private static ByteBuffer[] get(String heads)中的:
heads.length=>heads.length()
heads[i] ---The type of the expression must be an array type but it resolved to String

经过核对CODE,该方法从未被使用.故称之为简单错误.

刚刚又把你的源码再次复制粘贴,竟然可以了.不过方法"private static ByteBuffer[] get(String heads)"写得还是有问题.请验证.

  回复  更多评论
  
# re: NIO连接socket
2008-07-08 14:03 | 千里冰封
@冰河の泥鱼
private static ByteBuffer[] get(String... heads)
可能是你复制过去的时候没有发现String后面有三个点哦,呵呵,这是JDK1.5新加的可变参数,它表示的就是一个String[] heads
我也复制了一下代码,那三个点确实复制不下来. blogjava的代码块还是有点问题的  回复  更多评论
  
# re: NIO连接socket
2011-06-17 13:32 | epinszteinic
@千里冰封
那三个点它是用图片做的,当然复制不下来了。。。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: