问题描述
server发送数据给client,但是重复发送,不能清除缓冲,求解,谢谢!!另外请讲解一下flip(),position()的用法。请看send2()packagenonblock;importjava.io.*;importjava.nio.*;importjava.nio.channels.*;importjava.nio.charset.*;importjava.net.*;importjava.util.*;publicclassEchoServer{privateSelectorselector=null;privateServerSocketChannelserverSocketChannel=null;privateintport=8000;privateCharsetcharset=Charset.forName("GBK");publicEchoServer()throwsIOException{selector=Selector.open();serverSocketChannel=ServerSocketChannel.open();serverSocketChannel.socket().setReuseAddress(true);serverSocketChannel.configureBlocking(false);serverSocketChannel.socket().bind(newInetSocketAddress(port));System.out.println("服务器启动");}publicvoidservice()throwsIOException{serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);while(selector.select()>0){SetreadyKeys=selector.selectedKeys();Iteratorit=readyKeys.iterator();while(it.hasNext()){SelectionKeykey=null;try{key=(SelectionKey)it.next();it.remove();if(key.isAcceptable()){ServerSocketChannelssc=(ServerSocketChannel)key.channel();SocketChannelsocketChannel=(SocketChannel)ssc.accept();System.out.println("接收到客户连接,来自:"+socketChannel.socket().getInetAddress()+":"+socketChannel.socket().getPort());socketChannel.configureBlocking(false);ByteBufferbuffer=ByteBuffer.allocate(1024);socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE,buffer);}if(key.isReadable()){receive(key);}if(key.isWritable()){send2(key);}}catch(IOExceptione){e.printStackTrace();try{if(key!=null){key.cancel();key.channel().close();}}catch(Exceptionex){e.printStackTrace();}}}//#while}//#while}publicvoidsend(SelectionKeykey)throwsIOException{ByteBufferbuffer=(ByteBuffer)key.attachment();SocketChannelsocketChannel=(SocketChannel)key.channel();buffer.flip();//把极限设为位置,把位置设为0//在read或put后用Stringdata=decode(buffer);if(data.indexOf("rn")==-1)return;StringoutputData=data.substring(0,data.indexOf("n")+1);System.out.print(outputData);Stringdata1="bbbbbbbbbb";ByteBufferoutputBuffer=encode("echo:"+outputData);while(outputBuffer.hasRemaining())socketChannel.write(outputBuffer);ByteBuffertemp=encode(outputData);buffer.position(temp.limit());buffer.compact();if(outputData.equals("byern")){key.cancel();socketChannel.close();System.out.println("关闭与客户的连接");}}publicvoidreceive(SelectionKeykey)throwsIOException{ByteBufferbuffer=(ByteBuffer)key.attachment();SocketChannelsocketChannel=(SocketChannel)key.channel();ByteBufferreadBuff=ByteBuffer.allocate(32);socketChannel.read(readBuff);readBuff.flip();buffer.limit(buffer.capacity());buffer.put(readBuff);}publicStringdecode(ByteBufferbuffer){//解码CharBuffercharBuffer=charset.decode(buffer);returncharBuffer.toString();}publicByteBufferencode(Stringstr){//编码returncharset.encode(str);}publicstaticvoidmain(Stringargs[])throwsException{EchoServerserver=newEchoServer();server.service();}publicvoidsend2(SelectionKeykey)throwsIOException{ByteBufferbuffer=(ByteBuffer)key.attachment();SocketChannelsocketChannel=(SocketChannel)key.channel();buffer.put(encode("bbbbbbbbb"+"rn"));buffer.flip();//把极限设为位置socketChannel.write(buffer);//写入通道buffer.compact();buffer.clear();System.out.println(buffer.toString());}}/*****************************************************作者:孙卫琴**来源:<<Java网络编程精解>>**技术支持网址:www.javathinker.org****************************************************/
解决方案
解决方案二:
重复发送的关键就是要保持你的channel能重复使用。对应的key和channel应该配对。flip()makesabufferreadyforanewsequenceofchannel-writeorrelativegetoperations:Itsetsthelimittothecurrentpositionandthensetsthepositiontozero.关于Buffer里面的各个属性的所处位置:0<=mark<=position<=limit<=capacity