Java NIO系列教程(八) SocketChannel

摘要:
JavaNIO中的SocketChannel是连接到TCP网络套接字的通道。您可以通过以下两种方式创建SocketChannel:打开SocketChannel并连接到Internet上的服务器。当新连接到达ServerSocketChannel时,将创建一个SocketChannel。从SocketChannel读取的数据将被放入此缓冲区。Write()方法无法保证可以向SocketChannel写入多少字节。非阻塞模式和选择器非阻塞模式与选择器配合使用会更好。通过向选择器注册一个或多个SocketChannels,您可以询问选择器哪个通道已准备好读写。稍后将详细描述Selector和SocketChannel的组合。

Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:

  1. 打开一个SocketChannel并连接到互联网上的某台服务器。
  2. 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。

打开 SocketChannel

下面是SocketChannel的打开方式:

SocketChannel client = SocketChannel.open();
client.connect(new InetSocketAddress("172.0.0.1", 8888));
        
SocketChannel client = SocketChannel.open(new InetSocketAddress("172.0.0.1", 8888));

关闭 SocketChannel

当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:

client.close();

从 SocketChannel 读取数据

要从SocketChannel中读取数据,调用一个read()的方法之一。以下是例子:

        ByteBuffer buf = ByteBuffer.allocate(1024);
        client.read(buf);

首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。

然后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。

写入 SocketChannel

写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。示例如下:

        ByteBuffer buf = ByteBuffer.allocate(1024);
        String req = "Time";
        buf.put(req.getBytes());
        buf.flip();
        while(buf.hasRemaining()){
            client.write(buf);
        }

注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法无法保证能写多少字节到SocketChannel。所以,我们重复调用write()直到Buffer没有要写的字节为止。

非阻塞模式

可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。

connect()

如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。像这样:

socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("172.0.0.1", 80));
while(! socketChannel.finishConnect() ){
    //wait, or do something else...
}

write()

非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。前面已经有例子了,这里就不赘述了。

read()

非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。

非阻塞模式与选择器

非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等。Selector与SocketChannel的搭配使用会在后面详讲。

免责声明:文章转载自《Java NIO系列教程(八) SocketChannel》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用HMAILSERVER搭建邮件服务器iOS 16进制颜色和UIcolor的转换下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SQL Server 锁

from:http://www.cnblogs.com/kissdodog/p/3170036.html  锁是一种防止在某对象执行动作的一个进程与已在该对象上执行的其他进行相冲突的机制。也就是说,如果有其他人在操作某个对象,那么你旧不能在该对象上进行操作。你能否执行操作取决于其他用户正在进行的操作。 通过锁可以防止的问题   锁可以解决以下4种主要问题:...

分析带UMI标签的测序数据

分析带UMI标签的测序数据 20条回复 分析带UMI标签的测序数据 检测癌组织的低频突变,为了提高检测低频突变的灵敏度,往往进行高深度的测序。但样本之间存在交叉污染,测序有存在一定概率的错误,这些因素会导致高深度测序过程中将假阳性的信号放到,得到假阳性的结果。解决交叉污染的方法,有公司比如IDT采用唯一配对的样本index,只有配对的index中的rea...

[转]慎用InputStream的read()方法

InputStream此抽象类是表示字节输入流的所有类的超类。 我们从输入流中读取数据最常用的方法基本上就是如下3个read()方法了: 1、read()方法,这个方法从输入流中读取数据的下一个字节。返回 0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回值-1。 2、read(byte[]b,intoff,intlen)方法...

用ssh进行git clone出现 fatal: Could not read from remote repository.

问题:在通过MobaXterm进行ssh连接的服务器上用ssh进行git clone出现 fatal: Could not read from remote repository. 解决方法:proxychains git clone xxx 在git clone之前加上proxychains即可。...

项目中应该怎么选择MySQL的事务隔离级别

知识点总结 1.数据库默认隔离级别: mysql :Repeatable Read; oracle、sql server :Read Commited 2.mysql binlog的格式三种:statement,row,mixed 3.为什么mysql用的是Repeatable Read而不是Read Commited:在 5.0之前只有statement...

对于一万条数据量使用Oracle游标,存储过程,一般查询的速度的对比

一,创建ID自增长表格 1,创建序列 create sequence my_em_seq --序列名 minvalue 1--最小值 maxvalue 9999999999999999999999999999--最大值 start with 1--起始值 increment by 1--步 nocache;...