阻塞socket read 阻塞channel写一次是一个包么

3735人阅读
下面的代码是一个实例化SocketChannel的过程:
SocketChannel channel = SocketChannel.open();
//要设置连接超时
channel.socket().connect(addr,connectionTimeOut_ms);
//设置读超时
channel.socket().setSoTimeout(timeout_ms);
然后基于NIO的一贯性崇拜,会出现channel.read()读取数据
int java.nio.channels.ReadableByteChannel.read(ByteBuffer dst) throws IOException
Reads a sequence of bytes from this channel into the given buffer.
唯一不幸的是,这个SocketChannel的read()方法与Socket不同,是没有超时设置的!
所以上面做了一堆socket的超时设置,在Channel read毫无作用。具体可以查看
就解决这个问题上来说,还是建议用回传统的Socket阻塞试读取整个流。或者使用ReadableByteChannel这个类(不能解决读写双向的Channel阻塞问题),封装Socket流,多绕了一圈而已。
//i.读取buffer的chanel
InputStream is = sock.socket().getInputStream();
ReadableByteChannel readCh = Channels.newChannel(is);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:139260次
积分:1876
积分:1876
排名:第15343名
原创:171篇
转载:10篇
评论:25条
(1)(1)(2)(123)(1)(1)(2)(1)(1)(3)(9)(8)(6)(6)(3)(6)(8)关于NIO中的ServerSocketChannel和SocketChannel是什么关系
[问题点数:40分]
关于NIO中的ServerSocketChannel和SocketChannel是什么关系
[问题点数:40分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2013年3月 总版技术专家分月排行榜第二
2014年2月 Java大版内专家分月排行榜第一2013年8月 Java大版内专家分月排行榜第一2013年5月 Java大版内专家分月排行榜第一2013年4月 Java大版内专家分月排行榜第一2013年3月 Java大版内专家分月排行榜第一2013年2月 Java大版内专家分月排行榜第一
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。SocketChannel
死循环在读消息
[问题点数:40分,结帖人Busing]
SocketChannel
死循环在读消息
[问题点数:40分,结帖人Busing]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。关于NIO的socketChannel.write
[问题点数:40分,结帖人superliyubo]
关于NIO的socketChannel.write
[问题点数:40分,结帖人superliyubo]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。非阻塞式socket超时问题 - 开源中国社区
当前访客身份:游客 [
当前位置:
请问:注释中的3处,是否可以设置超时时间?如果可以,各处的含义是怎么理解呢?那客户端超时如何设置呢?
服务端监听代码
public void start() throws IOException{
s = Selector.open();
ssc = ServerSocketChannel.open();
ssc.configureBlocking(block);
ssc.socket().bind(new InetSocketAddress(host, port),backlog);
ssc.socket().setSoTimeout(Constant.TIME_OUT_SERVER);
status = Status.R
(&listening on &+port);
ssc.register(s, SelectionKey.OP_ACCEPT);
while (status != Status.Stoping && status != Status.Stoped){
int count = s.select();
if(count & 0){
SocketChannel client =
Iterator&SelectionKey& it = s.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey key = it.next();
it.remove();
if(key.isAcceptable()){
if(current.incrementAndGet() & maxClient){
client = (SocketChannel)ssc.accept();
client.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
client.configureBlocking(false);
connected(client,s);
if (key.isReadable()) {
client = (SocketChannel)key.channel();
client.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
client.configureBlocking(false);
recevieData(client,s);
} catch (IOException e) {
logger.error(&Error &,e);
if(client != null){
client.close();
} catch (Exception e2) {
current.decrementAndGet();
} finally {
if(s != null){
s.close();
} catch (IOException e) {
if(ssc != null){
ssc.close();
} catch (IOException e) {
客户端连接代码
public boolean connect() throws IOException{
if(keepAlive
&& s != null && s.isConnected() && state != TransState.Stoped){
if(s == null || !s.isOpen() || state == TransState.Stoped){
s = SocketChannel.open();
if(!s.isConnected() || state == TransState.Stoped){
s.connect(new InetSocketAddress(host, port));
s.socket().connect(new InetSocketAddress(host, port),Constant.TIME_OUT_CLIENT);
s.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
共有1个答案
<span class="a_vote_num" id="a_vote_num_
setSoTimeout:
With this option set to a non-zero timeout, a call to accept() for this ServerSocket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the ServerSocket is still valid. The option must be enabled prior to entering the blocking operation to have effect.
我觉得吧,服务器端设置第一个或者第二个二选一即可了,第二个的作用就是在轮询的时候,如果有连接,防止超时。而第一个就好比是个整体的设置,多有的连接都必须控制在这个时间内。第三个也差不多,都是key's channel is ready for reading的时候然后设置超时。
至于客户端,原理跟服务器端一样的。
随便一说,不知道对不对,呵呵。你可以拿代码测一下。。。
更多开发者职位上
有什么技术问题吗?
类似的话题

我要回帖

更多关于 linux socket 非阻塞 的文章

 

随机推荐