java非阻塞socket缓冲区问题

问题描述

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

时间: 2024-10-25 23:44:06

java非阻塞socket缓冲区问题的相关文章

关于java阻塞socket和非阻塞socket的应用区别

问题描述 关于java阻塞socket和非阻塞socket的应用区别 最近在学习NIO,在学习非阻塞Socket的时候 很困惑,不知道他相对于阻塞的Socket的优势 在哪,希望大神指点一二,在线等. 解决方案 阻塞就是一直等待结果返回,非阻塞就是立即返回,等有了结果了以后,再回调,事件通知你 解决方案二: 传统的阻塞式,每个连接必须要开一个线程来处理,并且没处理完线程不能退出. 非阻塞式,由于基于反应器模式,用于事件多路分离和分派的体系结构模式,所以可以利用线程池来处理.事件来了就处理,处理完

Java非阻塞通信

问题描述 有哪位大神在安卓系统上调过非阻塞通信,求教啊!!!! 解决方案

java非阻塞的socket,如何实现客户端之间能过服务器转发互相通信?

问题描述 我的想法是每连接一个客户端,就把ip+port+SocketChannel+SelectedKey+ByteBuffer都放入到一个对象中,再把对象放到HashMsap时.通过查找IP+PORT来查找对象信息,通过socketChannel和buffer写信息.A发给server,server发给B,但是B却收不到.请问查找到的channel和buffer能用吗? 解决方案 解决方案二:应该有超时断开连接

面向连接的socket数据处理过程以及非阻塞connect问题

对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后必须调用bind绑定到一个指定的地址,然后调用int listen(int sockfd, int backlog);进行监听.此时服务器socket允许客户端进行连接,backlog提示没被accept的客户连接请求队列的大小,系统决定实际的值,最大值定义为SOMAXCONN在头文件<sys/so

linux非阻塞的socket EAGAIN的错误处理【转】

转自:http://blog.csdn.net/tianmohust/article/details/8691644 版权声明:本文为博主原创文章,未经博主允许不得转载. 在Linux中使用非阻塞的socket的情形下. (一)发送时 当客户通过Socket提供的send函数发送大的数据包时,就可能返回一个EAGAIN的错误.该错误产生的原因是由于send 函数中的size变量大小超过了tcp_sendspace的值.tcp_sendspace定义了应用在调用send之前能够在kernel中缓存

深入理解并发/并行,阻塞/非阻塞,同步/异步

1. 阻塞,非阻塞 首先,阻塞这个词来自操作系统的线程/进程的状态模型中,如下图: 一个线程/进程经历的5个状态,创建,就绪,运行,阻塞,终止.各个状态的转换条件如上图,其中有个阻塞状态,就是说当线程中调用某个函数,需要IO请求,或者暂时得不到竞争资源的,操作系统会把该线程阻塞起来,避免浪费CPU资源,等到得到了资源,再变成就绪状态,等待CPU调度运行. 阻塞调用是指调用结果返回之前,调用者会进入阻塞状态等待.只有在得到结果之后才会返回. 非阻塞调用是指在不能立刻得到结果之前,该函数不会阻塞当前

yanf4j引入了客户端非阻塞API

yanf4j发布一个0.50-beta2版本,这个版本最重要的改进就是引入了客户端 连接非阻塞API,主要最近的工作要用到,所以添加了.两个核心类 TCPConnectorController和UDPConnectorController分别用于TCP和UDP的客户端 连接控制.例如,现在的UDP echo client可以写成: //客户端echo handler class EchoClientHandler extends HandlerAdapter { public void onRe

利用Python中SocketServer 实现客户端与服务器间非阻塞通信_python

利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信. 首先,先了解下SocketServer模块中可供使用的类: BaseServer:包含服务器的核心功能与混合(mix-in)类挂钩:这个类只用于派生,所以不会生成这个类的实例:可以考虑使用TCPServer和UDPServer. TCPServer/UDPServer:基本的网络同步TCP/UDP服务器. UnixStreamServer/ UnixDatagramServer:基本的基于文件同步TCP/UDP服务器.

Java网络编程从入门到精通(33):非阻塞I/O的缓冲区(Buffer)

如果将同步I/O方式下的数据传输比做数据传输的零星方式(这里的零星是指在数据传输的过程中是以零星的字节方式进行的),那么就可以将非阻塞I/O方式下的数据传输比做数据传输的集装箱方式(在字节和低层数据传输之间,多了一层缓冲区,因此,可以将缓冲区看做是装载字节的集装箱).大家可以想象,如果我们要运送比较少的货物,用集装箱好象有点不太合算,而如果要运送上百吨的货物,用集装箱来运送的成本会更低.在数据传输过程中也是一样,如果数据量很小时,使用同步I/O方式会更适合,如果数据量很大时(一般以G为单位),使