package org.jboss.netty.bootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineException; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import java.net.InetSocketAddress; import java.net.SocketAddress; /** * �ͻ���Channel������ */ public class ClientBootstrap extends Bootstrap { /** * û������ChannelFactory����IO����֮ǰҪsetFactory(ChannelFactory) */ public ClientBootstrap() { } /** * ��ָ���� ChannelFactory������ʵ��. */ public ClientBootstrap(ChannelFactory channelFactory) { super(channelFactory); } /** * ͨ����"localAddress"��������connect�� * ���"localAddress"û�� ���ã�����Զ����� * ���"remoteAddress"û�еĻ��ͻ��׳�IllegalStateException * �������ChannelPipelineʧ�ܣ���ChannelPipelineException */ public ChannelFuture connect() { SocketAddress remoteAddress = (SocketAddress) getOption("remoteAddress"); if (remoteAddress == null) { throw new IllegalStateException("remoteAddress option is not set."); } return connect(remoteAddress); } /** * �����ѡ���еõ���localAddress����SocketAddress���ͻ���null�ͻ��׳�ClassCastException * ������ͬ�� */ public ChannelFuture connect(SocketAddress remoteAddress) { if (remoteAddress == null) { throw new NullPointerException("remoteAddress"); } SocketAddress localAddress = (SocketAddress) getOption("localAddress"); return connect(remoteAddress, localAddress); } /** * ���ԺͶԶ����ӣ���� localAddress=null�������׽��ֵ�ַ���Զ����䣻 * * �����ӳ��Գɹ���ʧ�ܺ� ChannelFuture ����֪ͨ�� * * �������ChannelPipelineʧ�ܣ���ChannelPipelineException */ public ChannelFuture connect(final SocketAddress remoteAddress, final SocketAddress localAddress) { if (remoteAddress == null) { throw new NullPointerException("remoteAddress"); } ChannelPipeline pipeline; try { //����pipeline Factory�õ�һ����ˮ�� pipeline = getPipelineFactory().getPipeline(); } catch (Exception e) { throw new ChannelPipelineException("Failed to initialize a pipeline.", e); } //Set the options. //ChannelFactory����ָ����pipeline����һ��ͨ����������ʱ��ͻ�򿪣����翴 OioClientSocketChannel Channel ch = getFactory().newChannel(pipeline); boolean success = false; try { // ����ͨ�� ch.getConfig().setOptions(getOptions()); success = true; } finally { if (!success) { ch.close(); } } //����İ󶨣����Ӷ�����AbstractChannelʵ�ֵ�-ͨ��Channels�еľ�̬������ // Bind. if (localAddress != null) { ch.bind(localAddress); } // Connect.�������ջ����Channels.connect�������� return ch.connect(remoteAddress); } /** * �󶨲������ڰ󶨺�������Ҫ�ֿ���ʱ���õ��� * �����ڳ�������֮ǰ������ͨ��Channel.setAttachment(Object)Ϊ���ͨ������һ��attachment * ����һ�����ӽ��飬�Ϳ��Է������attachment */ public ChannelFuture bind(final SocketAddress localAddress) { if (localAddress == null) { throw new NullPointerException("localAddress"); } ChannelPipeline pipeline; try { pipeline = getPipelineFactory().getPipeline(); } catch (Exception e) { throw new ChannelPipelineException("Failed to initialize a pipeline.", e); } // Set the options. Channel ch = getFactory().newChannel(pipeline); boolean success = false; try { ch.getConfig().setOptions(getOptions()); success = true; } finally { if (!success) { ch.close(); } } // Bind. return ch.bind(localAddress); } }