国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【自己讀源碼】Netty4.X系列(二) 啟動(dòng)類成員Channel

waterc / 1018人閱讀

摘要:下面無恥的貼點(diǎn)源碼。啟動(dòng)類我們也學(xué),把啟動(dòng)類抽象成兩層,方便以后寫客戶端。別著急,我們慢慢來,下一篇我們會(huì)了解以及他的成員,然后,完善我們的程序,增加其接收數(shù)據(jù)的能力。文章的源碼我會(huì)同步更新到我的上,歡迎大家,哈哈。

廢話兩句

這次更新拖了很長(zhǎng)時(shí)間,第一是自己生病了,第二是因?yàn)樽铋_始這篇想寫的很大,然后構(gòu)思了很久,發(fā)現(xiàn)不太合適把很多東西寫在一起,所以做了點(diǎn)拆分,準(zhǔn)備國慶前完成這篇博客。

目的&&期望

開門見山,先說下這篇文章能學(xué)到什么

netty中channel的實(shí)現(xiàn)類的實(shí)現(xiàn)方式和作用

自己動(dòng)手寫netty框架的channel部分和bind方法,完成服務(wù)端的端口綁定

Bootstrap主要成員

上一篇我們看了Bootstrap類的大致的組成,也了解了它的一些配置方法,其實(shí)都是在設(shè)置它的成員變量,有些是ServerBootstrap的也有是它的父類AbstractBootstrap的,在這里,我覺得主要有下面幾個(gè)。

EventLoopGroup

Channel

Handler

當(dāng)然,這些只是它的一些接口,具體有多種實(shí)現(xiàn),除了Nio,它也有Bio等其他版本的,繼承鏈也很復(fù)雜,這里我們先看下channel的實(shí)現(xiàn)。

NioServerSocketChannel 繼承鏈

說到channel,它是Java Nio中的一個(gè)重要的成員,不過在netty中,channel是自己封裝的一個(gè)更抽象的東西,在Nio版本的實(shí)現(xiàn)中,它也維護(hù)了Java Nio的channel,不過這些都是后話了,我們先看一下它的繼承鏈,這里我自己畫了一個(gè)簡(jiǎn)單的。

這里可以看到,它的繼承有兩個(gè)分支,準(zhǔn)確的說一條線是繼承抽象類,一條線是實(shí)現(xiàn)接口,這么做,可以說是netty設(shè)計(jì)上的考慮,一方面,它是nio的channel,但是同時(shí)它又是server端的channel,所以netty選擇了這樣做來實(shí)現(xiàn)。

與Nio的摩擦

看到這里你可能會(huì)疑問,這個(gè)channel是netty自己封裝的,那他是怎么和Nio的channel發(fā)生碰撞的呢?
首先,它在構(gòu)造方法里利用Java Nio的selectProvider 打開了一個(gè)socketChannel,然后把這個(gè)Nio的Channel和它的準(zhǔn)備狀態(tài)傳給父類構(gòu)造器,然后父類構(gòu)造器里存儲(chǔ)到成員變量中。下面無恥的貼點(diǎn)源碼。

    public NioServerSocketChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
    //這個(gè)DEFAULT_SELECTOR_PROVIDER其實(shí)就是select的provide
    private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
    //然后是newSocket打開了一個(gè)Channel
    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }
    //最后是調(diào)用父類的構(gòu)造
     public NioServerSocketChannel(ServerSocketChannel channel) {
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

看到這些,我想大家對(duì)Channel有所了解了吧,現(xiàn)在我們來開始實(shí)現(xiàn)自己的版本

自己動(dòng)手 熱身

在這之前先說下bootstrap的bind方法,這邊netty實(shí)現(xiàn)的比較復(fù)雜,它是通過各種線程異步,還有它的一個(gè)內(nèi)部類unsafe,最后調(diào)用到NioServerSocketChannel的doBind方法,doBind在調(diào)用Java Nio的bind方法。這里我們先實(shí)現(xiàn)簡(jiǎn)單版本,它的關(guān)于線程的一些設(shè)計(jì),我們說到eventloop之后再說。

先來實(shí)現(xiàn)Channel和Channel工廠類,方便我們動(dòng)態(tài)new出不同的Channel。

public interface Channel {
    void bind(InetSocketAddress inetSocketAddress);
}

public interface ChannelFactory{

    T newChannel();
}

public class  ReflectChannelFactory implements ChannelFactory {

    private final Class clazz;

    public ReflectChannelFactory(Class clazz) {
        this.clazz = clazz;
    }

    public T newChannel() {
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException("can not init");
        }
    }

}
啟動(dòng)類

我們也學(xué)netty,把啟動(dòng)類抽象成兩層,方便以后寫客戶端。

public abstract class AbstractBootstrap,C extends Channel> {

    private ChannelFactory channelFactory;

    public B channel(Class clazz){
        this.channelFactory = new ReflectChannelFactory(clazz);
        return (B)this;
    }

    public B bind(Integer port){
        validate();
        doBind(port);
        return (B)this;
    }

    private  void doBind(Integer port){
        Channel channel = channelFactory.newChannel();
        channel.bind(new InetSocketAddress(port));
    }

    public void validate(){
        if(channelFactory == null){
            throw new IllegalArgumentException("channelFactory should be initialized");
        }
    }
}
//服務(wù)端暫時(shí)沒有用到額外的方法,先直接繼承就OK了
public class ServerBootstrap extends AbstractBootstrap{


}
Channel實(shí)現(xiàn)類

最后我們實(shí)現(xiàn)我們的NioChannel,相比netty,我們目前只做了兩層抽象。

public abstract class AbstractNioChannel  implements Channel{
    private final SelectableChannel ch;


    public AbstractNioChannel(SelectableChannel ch) {
        this.ch = ch;
    }

    protected SelectableChannel ch() {
        return ch;
    }

    protected abstract void doBind(SocketAddress localAddress) throws Exception;

    public void bind(InetSocketAddress inetSocketAddress) {
        try {
            doBind(inetSocketAddress);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class NioServerSocketChannel extends AbstractNioChannel {

    public NioServerSocketChannel() {

       super(newSocket());
    }

    private static ServerSocketChannel newSocket(){
        try {
            return SelectorProvider.provider().openServerSocketChannel();
        } catch (IOException e) {
            throw new IllegalArgumentException("can not open socket");
        }
    }

    @Override
    protected ServerSocketChannel ch(){
        return (ServerSocketChannel) super.ch();
    }

    @Override
    protected  void doBind(SocketAddress localAddress) throws Exception{
        ch().socket().bind(localAddress);
    }
}
測(cè)試

最后寫個(gè)測(cè)試類,來測(cè)試下

public class Test {
    public static void main(String[] args) {
        ServerBootstrap sb = new ServerBootstrap();
        sb.channel(NioServerSocketChannel.class).bind(9999);

    }
}
最后

當(dāng)然,這個(gè)連殘缺版netty都算不上,在綁定完端口后就自動(dòng)結(jié)束了。別著急,我們慢慢來,下一篇我們會(huì)了解EventLoopGroup以及他的成員EventLoop,然后,完善我們的程序,增加其接收數(shù)據(jù)的能力。
文章的源碼我會(huì)同步更新到我的gayHub上,歡迎大家star,哈哈。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/67641.html

相關(guān)文章

  • 自己源碼Netty4.X系列(一) 啟動(dòng)概覽

    摘要:一些想法這個(gè)系列想開很久了,自己使用也有一段時(shí)間了,利用也編寫了一個(gè)簡(jiǎn)單的框架,并運(yùn)用到工作中了,感覺還不錯(cuò),趁著這段時(shí)間工作不是很忙,來分析一波源碼,提升下技術(shù)硬實(shí)力。 一些想法 這個(gè)系列想開很久了,自己使用netty也有一段時(shí)間了,利用netty也編寫了一個(gè)簡(jiǎn)單的框架,并運(yùn)用到工作中了,感覺還不錯(cuò),趁著這段時(shí)間工作不是很忙,來分析一波源碼,提升下技術(shù)硬實(shí)力。 結(jié)構(gòu) 這里先看下net...

    qingshanli1988 評(píng)論0 收藏0
  • 自己源碼Netty4.X系列(三) Channel Register

    摘要:我想這很好的解釋了中,僅僅一個(gè)都這么復(fù)雜,在單線程或者說串行的程序中,編程往往是很簡(jiǎn)單的,說白了就是調(diào)用,調(diào)用,調(diào)用然后返回。 Netty源碼分析(三) 前提概要 這次停更很久了,原因是中途迷茫了一段時(shí)間,不過最近調(diào)整過來了。不過有點(diǎn)要說下,前幾天和業(yè)內(nèi)某個(gè)大佬聊天,收獲很多,所以這篇博文和之前也會(huì)不太一樣,我們會(huì)先從如果是我自己去實(shí)現(xiàn)這個(gè)功能需要怎么做開始,然后去看netty源碼,與...

    darkbug 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列):服務(wù)端bind流程詳解

    摘要:對(duì)于,目前大家只知道是個(gè)線程組,其內(nèi)部到底如何實(shí)現(xiàn)的,它的作用到底是什么,大家也都不太清楚,由于篇幅原因,這里不作詳細(xì)介紹,后面會(huì)有文章作專門詳解。 在上一篇《ServerBootstrap 與 Bootstrap 初探》中,我們已經(jīng)初步的了解了ServerBootstrap是netty進(jìn)行服務(wù)端開發(fā)的引導(dǎo)類。 且在上一篇的服務(wù)端示例中,我們也看到了,在使用netty進(jìn)行網(wǎng)絡(luò)編程時(shí),我...

    laoLiueizo 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列(一):ServerBootstrap 與 Bootstrap 初探

    摘要:而用于主線程池的屬性都定義在中本篇只是簡(jiǎn)單介紹了一下引導(dǎo)類的配置屬性,下一篇我將詳細(xì)介紹服務(wù)端引導(dǎo)類的過程分析。 從Java1.4開始, Java引入了non-blocking IO,簡(jiǎn)稱NIO。NIO與傳統(tǒng)socket最大的不同就是引入了Channel和多路復(fù)用selector的概念。傳統(tǒng)的socket是基于stream的,它是單向的,有InputStream表示read和Outpu...

    BakerJ 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列(三):NioServerSocketChannel全剖析

    摘要:本篇將通過實(shí)例化過程,來深入剖析。及初始化完成后,它們會(huì)相互連接。我們?cè)诨氐降臉?gòu)造方法父類構(gòu)造方法調(diào)用完成后,還要初始化一下自己的配置對(duì)象是的內(nèi)部類而又是繼承自,通過代碼分析,此對(duì)象就是就會(huì)對(duì)底層一些配置設(shè)置行為的封裝。 根據(jù)上一篇《Netty4.x 源碼實(shí)戰(zhàn)系列(二):服務(wù)端bind流程詳解》所述,在進(jìn)行服務(wù)端開發(fā)時(shí),必須通過ServerBootstrap引導(dǎo)類的channel方法來...

    Flink_China 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<