首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

socket服务类.在csdn花了5分上载上来的

2012-10-26 
socket服务类.在csdn花了5分下载下来的我当时花了5分下载下来的.在这里免费发布..有参考价值要给我留言啊.

socket服务类.在csdn花了5分下载下来的
我当时花了5分下载下来的.在这里免费发布..有参考价值要给我留言啊..做人要有人品的

package test.sockettest;/** *  * @author chenjd */import java.io.IOException;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.Socket;import java.nio.ByteBuffer;import java.nio.CharBuffer;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.nio.charset.CharacterCodingException;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.util.HashMap;import java.util.Iterator;import java.util.Set;public class NBServer {int port = 8090;int BUFFERSIZE = 1024;Selector selector = null;ServerSocketChannel serverChannel = null;HashMap clientChannelMap = null;// 用来存放每一个客户连接对应的套接字和通道public NBServer(int port) {this.clientChannelMap = new HashMap();this.port = port;}public void initialize() throws IOException {// 初始化,分别实例化一个选择器,一个服务器端可选择通道this.selector = Selector.open();this.serverChannel = ServerSocketChannel.open();this.serverChannel.configureBlocking(false);InetAddress localhost = InetAddress.getLocalHost();InetSocketAddress isa = new InetSocketAddress(localhost, this.port);this.serverChannel.socket().bind(isa);// 将该套接字绑定到服务器某一可用端口}// 结束时释放资源public void finalize() throws IOException {this.serverChannel.close();this.selector.close();}// 将读入字节缓冲的信息解码public String decode(ByteBuffer byteBuffer) throws CharacterCodingException {Charset charset = Charset.forName("ISO-8859-1");CharsetDecoder decoder = charset.newDecoder();CharBuffer charBuffer = decoder.decode(byteBuffer);String result = charBuffer.toString();return result;}// 监听端口,当通道准备好时进行相应操作public void portListening(String data) throws IOException, InterruptedException {// 服务器端通道注册OP_ACCEPT事件SelectionKey acceptKey = this.serverChannel.register(this.selector,SelectionKey.OP_ACCEPT);// 当有已注册的事件发生时,select()返回值将大于0while (acceptKey.selector().select() > 0) {System.out.println("event happened");// 取得所有已经准备好的所有选择键Set readyKeys = this.selector.selectedKeys();// 使用迭代器对选择键进行轮询Iterator i = readyKeys.iterator();while (i.hasNext()) {SelectionKey key = (SelectionKey) i.next();i.remove();// 删除当前将要处理的选择键if (key.isAcceptable()) {// 如果是有客户端连接请求System.out.println("more client connect in!");ServerSocketChannel nextReady = (ServerSocketChannel) key.channel();// 获取客户端套接字Socket s = nextReady.accept().socket();// 设置对应的通道为异步方式并注册感兴趣事件s.getChannel().configureBlocking(false);SelectionKey readWriteKey = s.getChannel().register(this.selector,SelectionKey.OP_READ | SelectionKey.OP_WRITE);// 将注册的事件与该套接字联系起来readWriteKey.attach(s);// 将当前建立连接的客户端套接字及对应的通道存放在哈希表//clientChannelMap中this.clientChannelMap.put(s, new ClientChInstance(s.getChannel()));} else if (key.isReadable()) {// 如果是通道读准备好事件System.out.println("Readable");// 取得选择键对应的通道和套接字SelectableChannel nextReady = (SelectableChannel) key.channel();Socket socket = (Socket) key.attachment();// 处理该事件,处理方法已封装在类ClientChInstance中this.readFromChannel(socket.getChannel(),(ClientChInstance) this.clientChannelMap.get(socket));} else if (key.isWritable()) {// 如果是通道写准备好事件System.out.println("writeable");// 取得套接字后处理,方法同上Socket socket = (Socket) key.attachment();SocketChannel channel = (SocketChannel) socket.getChannel();//this.writeToChannel(channel, "This is from server!");this.writeToChannel(channel, data);}}}}// 对通道的写操作public void writeToChannel(SocketChannel channel, String message)throws IOException {ByteBuffer buf = ByteBuffer.wrap(message.getBytes());int nbytes = channel.write(buf);}// 对通道的读操作public void readFromChannel(SocketChannel channel,ClientChInstance clientInstance) throws IOException,InterruptedException {ByteBuffer byteBuffer = null;try{byteBuffer = ByteBuffer.allocate(BUFFERSIZE);int nbytes = channel.read(byteBuffer);}catch(Exception e){clientChannelMap.remove(channel.socket());channel.close();e=null;return;}byteBuffer.flip();String result = this.decode(byteBuffer);// 当客户端发出”@exit”退出命令时,关闭其通道if (result.indexOf("@exit") >= 0||result.indexOf("q")>=0) {channel.close();}//else if(result.indexOf("@close") >= 0){//关闭服务//channel.close();//this.finalize();//}else {clientInstance.append(result.toString());// 读入一行完毕,执行相应操作if (result.indexOf("\n") >= 0) {System.out.println("client input" + result);clientInstance.execute();}}}// 该类封装了怎样对客户端的通道进行操作,具体实现可以通过重载execute()方法public class ClientChInstance {SocketChannel channel;StringBuffer buffer = new StringBuffer();public ClientChInstance(SocketChannel channel) {this.channel = channel;}public void execute() throws IOException {String message = "This is response after reading from channel!";writeToChannel(this.channel, message);buffer = new StringBuffer();}// 当一行没有结束时,将当前字窜置于缓冲尾public void append(String values) {buffer.append(values);}}// 主程序public static void main(String[] args) {NBServer nbServer = new NBServer(8090);try {nbServer.initialize();} catch (Exception e) {e.printStackTrace();System.exit(-1);}try {nbServer.portListening("This is from server!");} catch (Exception e) {e.printStackTrace();}}}
好一个事件驱动模型 3 楼 wupuyuan 2011-09-14   谢谢分享,一定要顶下 4 楼 lsrjava 2011-11-10   学习一下,感谢楼主的分享啊 5 楼 chasewade 2012-02-10   多谢分享啊 6 楼 dizhuang 2012-02-13   我搞不懂为什么需要注册Write事件,我注册Read了,一边读取一边处理不就可以了。

热点排行