NIO之SocketChannel简单使用
来源:互联网 发布:狸窝转换器mac版 编辑:程序博客网 时间:2024/05/21 09:15
客户端:
import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;public class SocketChannelTest{public static void main(String[] args) throws IOException{SocketChannel socket = SocketChannel.open();socket.configureBlocking(false);//设置非阻塞状态 则在connect返回之前可以执行下一步while(!socket.finishConnect())判断socket.connect(new InetSocketAddress("localhost",50000));//如果不设置为非阻塞模式 则connect是阻塞方法 while(!socket.finishConnect()){System.out.println("waiting");}ByteBuffer buffer = ByteBuffer.allocate(1024);int i = -100;while((i = socket.read(buffer))!=-1){//读取信息 默认为阻塞的 可通过socket.configureBlocking(false)设置为非阻塞 非阻塞模式下 返回读取的文件字节数 如果没有 则返回0 如果该通道已到达流的末尾,则返回 -1 if( i != 0){buffer.flip();//一定要flip,read会改变position的值System.out.println(buffer.position()+" "+buffer.limit());String info = getString(buffer);System.out.println(info);buffer.clear();}}System.out.println("done");socket.close();}/** * 将ByteBuffer转成字符串 * @param buffer * @return */public static String getString(ByteBuffer buffer) { Charset charset = null; CharsetDecoder decoder = null; CharBuffer charBuffer = null; try { charset = Charset.forName("UTF-8"); decoder = charset.newDecoder(); // charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空 charBuffer = decoder.decode(buffer.asReadOnlyBuffer()); return charBuffer.toString(); } catch (Exception ex) { ex.printStackTrace(); return ""; } } }
这里需要注意的是:
在非阻塞模式下调用connect( )方法之后,SocketChannel又被切换回了阻塞模式。那么如果有必要的话,调用线程会阻塞直到连接建立完成,finishConnect( )方法接着就会返回true值。
设置非阻塞模式时一定要调用finishConnect()来完成连接 否则读写操作将会报错NotYetConnectedException
下面是finishConnect的API解释:
finishConnect
public abstract boolean finishConnect() throws IOException
- 完成套接字通道的连接过程。
通过将套接字通道置于非阻塞模式,然后调用其
connect
方法来发起非阻塞连接操作。一旦建立了连接,或者尝试已失败,该套接字通道就变为可连接的,并且可调用此方法完成连接序列。如果连接操作失败,则调用此方法将导致抛出合适的IOException
。如果已连接了此通道,则不阻塞此方法并且立即返回 true。如果此通道处于非阻塞模式,那么当连接过程尚未完成时,此方法将返回 false。如果此通道处于阻塞模式,则在连接完成或失败之前将阻塞此方法,并且总是返回true 或抛出描述该失败的、经过检查的异常。
可在任意时间调用此方法。如果正在调用此方法时在此通道上调用读取或写入操作,则在此调用完成前将首先阻塞该操作。如果试图发起连接但失败了,也就是说如果调用此方法导致抛出经过检查的异常,则关闭此通道。
- 返回:
- 当且仅当已连接此通道的套接字时才返回 true
- 抛出:
NoConnectionPendingException
- 如果未连接此通道并且尚未发起连接操作ClosedChannelException
- 如果此通道已关闭AsynchronousCloseException
- 如果正在进行连接操作时另一个线程关闭了此通道ClosedByInterruptException
- 如果正在进行连接操作时另一个线程中断了当前线程,因此关闭了该通道并将当前线程设置为中断状态IOException
- 如果发生其他 I/O 错误
关于SocketChannel的read方法返回值:
(read后position的值会变化)
转自http://blog.csdn.net/pingnanlee/article/details/9712439
1、read什么时候返回-1read返回-1说明客户端的数据发送完毕,并且主动的close socket。所以在这种场景下,你需要关闭socketChannel并且取消key,最好是退出当前函数。注意,这个时候服务端要是继续使用该socketChannel进行读操作的话,就会抛出“远程主机强迫关闭一个现有的连接”的IO异常。
2、read什么时候返回0
其实read返回0有3种情况,一是某一时刻socketChannel中当前(注意是当前)没有数据可以读,这时会返回0,其次是bytebuffer的position等于limit了,即bytebuffer的remaining等于0,这个时候也会返回0,最后一种情况就是客户端的数据发送完毕了,这个时候客户端想获取服务端的反馈调用了recv函数,若服务端继续read,这个时候就会返回0。
服务端:
import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;import java.nio.ByteBuffer;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;public class ServerSocketChannelTest{public static void main(String[] args) throws IOException{int port = 50000;ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(port)); //绑定端口serverSocketChannel.configureBlocking(false); //设置成非阻塞模式 即不会再accept因为等待连接而阻塞 如果没有连接则立即返回null //System.out.println(serverSocketChannel.isBlocking());while(true){SocketChannel socket = serverSocketChannel.accept();if(socket!=null){System.out.println("accept connect from "+socket.getLocalAddress());ByteBuffer buffer = ByteBuffer.allocate(1024);buffer.put("hello".getBytes());//法送hello信息buffer.flip();//position回置socket.write(buffer);}}}}
0 0
- NIO之SocketChannel简单使用
- NIO之SocketChannel;ServerSocketChannel
- Java NIO之SocketChannel
- NIO之SocketChannel
- Java NIO 之 ServerSocketChannel SocketChannel
- NIO SocketChannel
- 9.Java NIO系列教程之SocketChannel
- Java之NIO(二)selector socketChannel
- NIO边看边记 之 SocketChannel(八)
- Java的NIO之网络通信的SocketChannel
- Java网络编程之NIO(ServerSocketChannel/SocketChannel)-yellowcong
- 使用SocketChannel的NIO客户机服务器通信示例。(转)
- 使用SocketChannel的NIO客户机服务器通信示例
- 使用SocketChannel的NIO客户机服务器通信示例。(转)
- 使用SocketChannel的NIO客户机服务器通信示例。(转)
- 使用SocketChannel的NIO客户机服务器通信示例。(转)
- 使用SocketChannel的NIO客户机服务器通信示例。(转)
- 使用SocketChannel的NIO客户机服务器通信示例
- SSH开发包结构划分
- ubuntu开机自动进入终端模式
- VC中关于 0xcccccccc、0xcdcdcdcd和 0xfeeefeee 异常值说明
- 鼠标移过图片变高亮
- 最长公共子序列的一个应用
- NIO之SocketChannel简单使用
- 容器搜索算法的选择
- 简谈Cookie和Session机制与实际应用
- 安卓技术收录
- wcf服务寄宿时,如何指定终结点三要素才不会出错
- 超实用PHP函数总结整理
- 从装饰设计模式角度学习JavaIO字节流
- 第6章 使用Linux环境变量
- android fragment与activity交互demo