java select单线程 服务器
阅读原文时间:2023年07月08日阅读:2

package com.Select;
/*
*

*select单线程 服务器

*
*/

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Myselect {
private Map map = new HashMap();

public static void main(String\[\] args) {  
    // TODO Auto-generated method stubnew Myselect().initsocket();  
}

public void initsocket(){  
    ServerSocketChannel ssc=null;  
    Selector selector=null;  
    Iterator<SelectionKey> iter=null;  
    try {  
        ssc = ServerSocketChannel.open();  
        ssc.socket().setReuseAddress(true);  
        ssc.socket().bind(new InetSocketAddress(8081));  
        selector = Selector.open();  
        ssc.configureBlocking(false);  
        ssc.register(selector, SelectionKey.OP\_ACCEPT);  
    } catch (IOException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }  
    while (true) {  
        try {  
            int keys = selector.select(1000);  
            if (keys <= 0)  
                continue;  
            iter=null;  
            Set<SelectionKey> set\_key = selector.selectedKeys();  
            iter= set\_key.iterator();  
        } catch (Exception e) {  
            // TODO: handle exception  
        }  
        while (iter.hasNext()) {  
            SelectionKey key = iter.next();  
            iter.remove();  
            if (key.isAcceptable()) {  
                try {  
                    SocketChannel client = ssc.accept();  
                    client.configureBlocking(false);  
                    client.register(selector, SelectionKey.OP\_READ);  
                } catch (ClosedChannelException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            } else if (key.isReadable()) {  
                SocketChannel client = (SocketChannel) key.channel();  
                ByteBuffer dst = ByteBuffer.allocate(4094);  
                StringBuffer sb = new StringBuffer();  
                int readsize = -1;  
                try {  
                    while ((readsize = client.read(dst)) > 0) {  
                        dst.flip();  
                        sb.append(new String(dst.array(), 0, readsize));  
                        dst.clear();  
                        if (readsize < 0) {//对端关闭,read 返回-1,没有数据返回0,如果客户端一直没有发送数据则isReadable事件激发不了。  
                            System.out.println("client "  
                                    + ((InetSocketAddress) client.getRemoteAddress()).getAddress().getHostAddress()  
                                    + " is closed");  
                            key.cancel();//取消select 监听并关闭服务端socket.  
                            client.close();  
                            continue;  
                        }  
                        map.put(client, sb.toString());//  
                        System.out.println("server read : "+sb.toString());  
                        client.register(selector, SelectionKey.OP\_WRITE);  
                    }  
                } catch (Exception e) {  
                    // TODO: handle exception  
                }

            } else if (key.isWritable()) {  
                System.out.println("coming write\\n");  
                SocketChannel client = (SocketChannel) key.channel();  
                String req = map.get(client);  
                if(req==null) {  
                    continue;  
                }  
                System.out.println("ready write len"+req.length());  
                String httpResponse = "HTTP/1.1 200 OK\\r\\n" +  
                        "Content-Length: "+req.length()+"\\r\\n" +  
                        "Content-Type: text/html\\r\\n" +  
                        "\\r\\n" +req;  

// int wcode=client.write(ByteBuffer.wrap(httpResponse.getBytes()));
try {//捕捉异常,客户端端可能关闭导致写异常。
int wcode=client.write(ByteBuffer.wrap(req.getBytes()));
System.out.println("write code "+wcode);
client.register(selector, SelectionKey.OP_READ);
} catch (Exception e) {
// TODO: handle exception
map.remove(client);//关闭服务器端socket,并取消监听
key.cancel();
System.out.println("client is closed!");
try {
client.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}
}
}