博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket通道
阅读量:6310 次
发布时间:2019-06-22

本文共 3642 字,大约阅读时间需要 12 分钟。

Socket通道

socket通道与文件通道有不一样的特征:

1.socket通道类可以运行与非阻塞模式并且是可选择的,这两个性能可以激活大程序(比如网络服务器和中间件组件)巨大的可伸缩和灵活性,因此,再也没有为每个socket连接使用一个线程的必要了。借助NIO类,一个或者几个线程可以管理成百上千的活动socket连接了,并且只有很少甚至没有性能的损失。

2.全部socket通道类(DatagramChannel、SocketChannel,ServerSocketChannel)被实例化时都会创建一个对应的socket对象,也就是来自java.net的类(Datagram,socket,serverSocket),这些socket可以通过调用socket()方法从通道类获取,另外,这三个类都有getChannel方法获取通道。

3.每一个socket通道都有一个关联的socket对象,反之不是。如果直接实例化的方式创建一个socket对象,它就不会有关联的socketChannel,调用它的getChannel方法将总是返回null。

 

非阻塞模式

传统java socket的阻塞性质曾经是java程序可伸缩性的最重要制约之一,非阻塞io是许多复杂的,高性能的程序构建的基础。

要把一个socket通道置于非阻塞模式,要依赖的是socket通道类的SelectableChannel。

public abstract class SelectableChannel extends AbstractInterruptibleChannel implements Channel{    ...    public abstract void configureBlocking(boolean block) throws IOException;    public abstract boolean isBlocking();    public abstract Object blockngLock();    ...}

 

从该api中可以看出,设置或重新设置一个通道的阻塞模式是很简单的,只要调用configureBlocking方法即可,参数的true为阻塞模式,参数为false设为非阻塞模式。isBloking方式是判断某个socket通道处于哪种模式。偶尔,我们需要防止socket通道的阻塞模式被修改,所以有一个

blockingLock方法,该方法返回一个非透明对象引用,返回的对象是通道实现修改阻塞模式时内部使用的,只有拥有该对象的锁的线程才可以修改通道的阻塞模式,对于确保在执行代码关键部分时socket通道的阻塞模式不会改变,以及在不影响其他线程的前提下暂时改变阻塞模式来说,

这个方法是非常方便的。

 

服务端

public static void main(String[] args) throws Exception {        int port = 9090;        if (args != null && args.length > 0) {            port = Integer.parseInt(args[0]);        }        ServerSocketChannel ssc = ServerSocketChannel.open();// 打开一个ServerSocketChannel对象。        ssc.configureBlocking(false);// 设置该通道是非阻塞式的        ssc.bind(new InetSocketAddress(port));// 绑定端口        System.out.println("开始等待客户端的数据!时间为" + System.currentTimeMillis());        while (true) {            SocketChannel sc = ssc.accept();            if (sc == null) {                // 如果当前没有数据,等待1秒钟再次轮询是否有数据,在学习了Selector之后此处可以使用Selector                Thread.sleep(1000);            } else {                System.out.println("客户端已有数据到来,客户端ip为:"                        + sc.socket().getRemoteSocketAddress() + ", 时间为"                        + System.currentTimeMillis());                ByteBuffer bb = ByteBuffer.allocate(100);// 初始化一个缓冲区                sc.read(bb);                bb.flip();                while (bb.hasRemaining()) {                    System.out.print((char) bb.get());// get方法一次获取一个字节,然后position往后移动一个位置。                }                sc.close();                System.exit(0);            }        }    }

 

客户端

服务端经常会使用非阻塞socket通达,因为它们使同时管理很多socket通道变得更容易,客户端不强求,因为客户端发起的socket操作往往比较少,且都一个个发起的。但是,在客户端使用一个或几个非阻塞模式的socket通道也是有益处的,比如借助非阻塞socket通道,gui程序可以

专注于用户请求并同时维护与一个或多个服务器的会话。在很多程序上,非阻塞模式都是有用的。

1 public class EchoClient { 2     private static final String STR = "Hello World!"; 3     private static final String REMOTE_IP = "127.0.0.1"; 4  5     public static void main(String[] args) throws Exception { 6         int port = 9090; 7         if (args != null && args.length > 0) { 8             port = Integer.parseInt(args[0]); 9         }10         SocketChannel sc = SocketChannel.open();11         sc.configureBlocking(false);12         sc.connect(new InetSocketAddress(REMOTE_IP, port));13         while (!sc.finishConnect()) {14             System.out.println("同" + REMOTE_IP + "的连接正在建立,请稍等!");15             Thread.sleep(10);16         }17         System.out.println("连接已建立,待写入内容至指定ip+端口!时间为"18                 + System.currentTimeMillis());19         ByteBuffer bb = ByteBuffer.allocate(STR.length());20         bb.put(STR.getBytes());21         bb.flip(); // 写缓冲区的数据之前一定要先反转(flip)22         sc.write(bb);//会把position到limit的内容写到通道里面,如果没有调用flip,那么就是空。23         bb.clear();24         sc.close();25     }26 }

 

转载于:https://www.cnblogs.com/tp123/p/6438936.html

你可能感兴趣的文章
第4 章序列的应用
查看>>
Mysql explain
查看>>
初识闭包
查看>>
java tcp socket实例
查看>>
011 指针的算术运算
查看>>
hdu1874畅通工程续
查看>>
rails 字符串 转化为 html
查看>>
java-学习8
查看>>
AOP动态代理
查看>>
Oracle序列
查看>>
xcodebuild命令行编译错误问题解决
查看>>
Yii2.0 下的 load() 方法的使用
查看>>
华为畅玩5 (CUN-AL00) 刷入第三方twrp Recovery 及 root
查看>>
LeetCode----67. Add Binary(java)
查看>>
母版页 MasterPage
查看>>
[转] ReactNative Animated动画详解
查看>>
DNS原理及其解析过程
查看>>
记录自写AFNetWorking封装类
查看>>
没想到cnblog也有月经贴,其实C#值不值钱不重要。
查看>>
【转】LUA内存分析
查看>>