上一篇博客【Netty源码分析】Netty服务端bind端口过程 我们介绍了服务端绑定端口的过程,这一篇博客我们介绍一下客户端连接服务端的过程。

ChannelFuture future = boostrap.connect("127.0.0.1", 8080).sync();  

调用BootStrap的connect函数

public ChannelFuture connect(String inetHost, int inetPort) {
        return connect(InetSocketAddress.createUnresolved(inetHost, inetPort));
}
public ChannelFuture connect(SocketAddress remoteAddress) {
        if (remoteAddress == null) {
            throw new NullPointerException("remoteAddress");
        }

        validate();
        return doResolveAndConnect(remoteAddress, config.localAddress());
    }

调用doResolveAndConnect函数

 private ChannelFuture doResolveAndConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
    ........
    return doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise());
    ........
}
private ChannelFuture doResolveAndConnect0(final Channel channel, SocketAddress remoteAddress,
                                               final SocketAddress localAddress, final ChannelPromise promise)
	........

    doConnect(remoteAddress, localAddress, promise);

	........

}

调用doConnect函数时会同时开启一个线程,用来处理客户端的操作。

 private static void doConnect(
            final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise connectPromise) {

        // This method is invoked before channelRegistered() is triggered.  Give user handlers a chance to set up
        // the pipeline in its channelRegistered() implementation.
        final Channel channel = connectPromise.channel();
        channel.eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                if (localAddress == null) {
                    channel.connect(remoteAddress, connectPromise);
                } else {
                    channel.connect(remoteAddress, localAddress, connectPromise);
                }
                connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
            }
        });
    }

AbstractChannel的connect函数

@Override
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
        return pipeline.connect(remoteAddress, localAddress, promise);
}
@Override
public final ChannelFuture connect(
            SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
        return tail.connect(remoteAddress, localAddress, promise);
}
private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
        if (invokeHandler()) {
            try {
                ((ChannelOutboundHandler) handler()).connect(this, remoteAddress, localAddress, promise);
            } catch (Throwable t) {
                notifyOutboundHandlerException(t, promise);
            }
        } else {
            connect(remoteAddress, localAddress, promise);
        }
    }

HeadContext的connect函数

@Override
public void connect(
                ChannelHandlerContext ctx,
           SocketAddress remoteAddress, SocketAddress localAddress,
                ChannelPromise promise) throws Exception {
  unsafe.connect(remoteAddress, localAddress, promise);
}

AbstractUnsafe函数的connect函数

@Override
public final void connect(
                final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
    .......

    if (doConnect(remoteAddress, localAddress)) {
        fulfillConnectPromise(promise, wasActive);
    }

	.......
}

调用NioSocketChannle的doConnect函数

 @Override
    protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
        if (localAddress != null) {
            doBind0(localAddress);
        }

        boolean success = false;
        try {
            boolean connected = javaChannel().connect(remoteAddress);
            if (!connected) {
                selectionKey().interestOps(SelectionKey.OP_CONNECT);
            }
            success = true;
            return connected;
        } finally {
            if (!success) {
                doClose();
            }
        }
    }

或许执行doBind0函数

private void doBind0(SocketAddress localAddress) throws Exception {
        if (PlatformDependent.javaVersion() >= 7) {
            javaChannel().bind(localAddress);
        } else {
            javaChannel().socket().bind(localAddress);
        }
    }

javaChannle()函数获得的就是SocketChannle对象,这样就完成了客户端连接服务端的操作。

【Netty源码分析】客户端connect服务端过程的更多相关文章

  1. Netty 源码(一)服务端启动

    Netty 源码(一)服务端启动 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) ServerBootstap 创建时序图如 ...

  2. Netty源码分析 (七)----- read过程 源码分析

    在上一篇文章中,我们分析了processSelectedKey这个方法中的accept过程,本文将分析一下work线程中的read过程. private static void processSele ...

  3. Fresco 源码分析(三) Fresco服务端处理(1) ImagePipeline为何物

    4.3 服务端的处理 备注: 因为是分析,而不是设计,所以很多知识我们类似于插叙的方式叙述,就是用到了哪个知识点,我们再提及相关的知识点,如果分析到了最后,我想想是不是应该将这个架构按照设计的方式,重 ...

  4. Fresco 源码分析(三) Fresco服务端处理(2) Producer具体实现的内容

    我们以mProducerFactory.newNetworkFetchProducer()为例,因为这些创建新的producer的方式类似,区别在于是否有包装的处理器,即如果当前处理器中没有正在处理的 ...

  5. (二)Netty源码学习笔记之服务端启动

    尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6129971.html  本文将不会对netty中每个点分类讲解,而是一个服务端启 ...

  6. Fresco 源码分析(三) Fresco服务端处理(3) DataSource到Producer的适配器逻辑以及BitmapMemoryCacheProducer处理的逻辑

    4.3.1.2.1 Producer和DataSource之间适配器处理的逻辑 还是从程序的入口开始说吧 CloseableProducerToDataSourceAdapter.create() 源 ...

  7. Netty源码分析 (八)----- write过程 源码分析

    上一篇文章主要讲了netty的read过程,本文主要分析一下write和writeAndFlush. 主要内容 本文分以下几个部分阐述一个java对象最后是如何转变成字节流,写到socket缓冲区中去 ...

  8. 【Netty源码分析】发送数据过程

    前面两篇博客[Netty源码分析]Netty服务端bind端口过程和[Netty源码分析]客户端connect服务端过程中我们分别介绍了服务端绑定端口和客户端连接到服务端的过程,接下来我们分析一下数据 ...

  9. Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化

    Netty源码分析第一章:  Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的 ...

随机推荐

  1. hihocoder 1419 重复旋律4

    描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段旋律称为(k,l)-重复的, ...

  2. ●UOJ58 [WC2013]糖果公园

    题链: http://uoj.ac/problem/58题解: 树上带修莫队. 每个块的大小为$n^{\frac{2}{3}}$,在dfs时,把点集分为若干块. 然后类似序列带修莫队,三个关键字:be ...

  3. Linux上安装Libssh2

    由于项目需要使用libssh2,在安装时,遇到一些问题,发现网上的都是互相抄,把自己遇到的问题,记下来,希望可以帮助到别人,自己下次使用时候,也方便查找,节约时间. 安装的流程: 1.下载源码,wge ...

  4. SPOJ VLATTICE(莫比乌斯反演)

    题意: 在一个三维空间中,已知(0,0,0)和(n,n,n),求从原点可以看见多少个点 思路: 如果要能看见,即两点之间没有点,所以gcd(a,b,c) = 1         /*来自kuangbi ...

  5. 字符串的最长回文串:Manacher’s Algorithm

    题目链接:Longest Palindromic Substring 1. 问题描述 Given a string S, find the longest palindromic substring ...

  6. React Suite v3.0 正式版发布

    React Suite v3.0 正式版发布 相信很多人会好奇,React Suite 是什么? React Suite 是 HYPERS 前端团队和 UX 团队开源的一套基于 React 的 UI ...

  7. nodejs基础教程回顾01

    最近在复习nodejs,因为框架太多隔一段时间不用就会忘了,所以没办法必须时常拿出来练练,就像家里有好几辆车,要时不常的轮流开一圈.我就从最基础的开始写,怎么下载安装就不说了,首先是nodejs的三类 ...

  8. IOS charles抓包HTTP

    charles通常用来截取本地的网络封包,但也可以用它来截取其他设备上的网络请求.本篇以IOS为例,讲解如何进行相应的操作. 1.charles上的设置 要截取iphone上的网络请求,我们要先将ch ...

  9. ajax跨域请求问题及解决办法总结

    1.浏览器的同源策略及规避方法 目前,所有浏览器都实行同源政策.即协议.域名.端口都相同的URI称为"同源".不同源的url之间: a.无法读取cookie.localstorag ...

  10. Spring-cloud(六) Hystrix入门

    前提 一个可用的Eureka注册中心(文中以之前博客中双节点注册中心,不重要) 一个连接到这个注册中心的服务提供者 快速入门 项目搭建 搭建一个新maven项目,artifactid为Ribbon-c ...