http://fokman.iteye.com/blog/1684330
今日将android里面使用的socket 方式改成Oio,因为之前使用的是Netty框架,所以直接将Nio替换成Oio,然后修改了一些其他的代码。
为了维护的方便我定义了一个BaseClient,用来处理停止socket线程。
- public abstract class BaseClient {
- protected Channel m_channel;
- protected String m_tag;
- public BaseClient(String tag) {
- m_tag = tag;
- }
- public Channel getChannel() {
- return m_channel;
- }
- public void stop(boolean releaseResOnly) {
- this.stopInThread(releaseResOnly);
- }
- protected void createBootstrap() {
- System.setProperty("java.net.preferIPv4Stack", "true");
- System.setProperty("java.net.preferIPv6Addresses", "false");
- }
- protected void stopInThread(Bootstrap bootstrap, boolean releaseResOnly) {
- try {
- final Bootstrap bs = bootstrap;
- final Channel ch = m_channel;
- final boolean resOnly = releaseResOnly;
- m_channel = null;
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- if (!resOnly) {
- if (ch != null) {
- ch.getCloseFuture().addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture cf) throws Exception {
- if (bs != null) {
- final Bootstrap bs2 = bs;
- new Thread(new Runnable() {
- public void run() {
- try {
- System.out.println(m_tag
- + "--- netty ch.close and releaseExtraRes-1");
- bs2.releaseExternalResources();
- System.out.println(m_tag
- + "--- netty ch.close and releaseExtraRes-1 done");
- } catch (Throwable th) {
- }
- }
- }).start();
- }
- }
- });
- ch.close();
- }
- } else {
- if (bs != null) {
- try {
- System.out.println(m_tag + "--- netty releaseExtraRes-2");
- bs.releaseExternalResources();
- System.out.println(m_tag + "--- netty releaseExtraRes-2 done");
- } catch (Throwable th) {
- }
- }
- }
- } catch (Exception ee) {
- ee.printStackTrace();
- }
- }
- });
- t.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }//stopInThread()
- protected abstract void stopInThread(boolean releaseResOnly);
CxClient继承了BaseClient,增加了一些关于不同的错误编码,方便在日志中查看
- public class CxClient extends BaseClient {
- private ClientBootstrap m_bootstrap;
- private CxListener m_listener;
- private final Timer timer;
- public CxClient(String tag) {
- super(tag);
- timer = new HashedWheelTimer();
- }
- @Override
- protected void createBootstrap() {
- super.createBootstrap();
- m_bootstrap = new ClientBootstrap(new OioClientSocketChannelFactory(Executors.newCachedThreadPool()));
- final CxClient client = this;
- m_bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- ChannelPipeline pip = Channels.pipeline();
- pip.addLast("timeout", new ReadTimeoutHandler(timer, 300));
- pip.addLast("decoder", new CxDecoder());
- pip.addLast("handler", new CxHandler(m_listener, client));
- return pip;
- }
- });
- m_bootstrap.setOption("tcpNoDelay", true);
- m_bootstrap.setOption("keepAlive", true);
- m_bootstrap.setOption("reuseAddress", true);
- m_bootstrap.setOption("connectTimeoutMillis", "7000");
- }
- public void start(String host, int port, CxListener li) {
- try {
- m_listener = li;
- createBootstrap();
- System.out.println("CxClient::start() Connecting... " + host + ":" + port);
- ChannelFuture f = m_bootstrap.connect(new InetSocketAddress(host, port));
- f.addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture cf) throws Exception {
- if (m_listener != null) {
- if (cf.isSuccess()) {
- m_channel = cf.getChannel();
- m_listener.connected();
- } else {
- Throwable th = cf.getCause();
- System.out.println("CxClient::start() A 1");
- int errorCode = CxnetConstants.UNKNOWN_EXCEPTION;
- if (th != null) {
- Class<?> c = th.getClass();
- if (c == java.net.BindException.class)
- errorCode = CxnetConstants.BIND_EXCEPTION;
- else if (c == java.net.ConnectException.class)
- errorCode = CxnetConstants.CONNECT_EXCEPTION;
- else if (c == java.net.MalformedURLException.class)
- errorCode = CxnetConstants.MAILFORMEDURL_EXCEPTION;
- else if (c == java.net.NoRouteToHostException.class)
- errorCode = CxnetConstants.NOROUTETOHOST_EXCEPTION;
- else if (c == java.net.PortUnreachableException.class)
- errorCode = CxnetConstants.PORTUNREACHABLE_EXCEPTION;
- else if (c == java.net.ProtocolException.class)
- errorCode = CxnetConstants.PROTOCOL_EXCEPTION;
- else if (c == java.net.SocketException.class)
- errorCode = CxnetConstants.SOCKET_EXCEPTION;
- else if (c == java.net.SocketTimeoutException.class)
- errorCode = CxnetConstants.SOCKETTIMEOUT_EXCEPTION;
- else if (c == java.net.UnknownHostException.class)
- errorCode = CxnetConstants.UNKNOWNHOST_EXCEPTION;
- else if (c == java.net.UnknownServiceException.class)
- errorCode = CxnetConstants.UNKNOWNSERVICE_EXCEPTION;
- else if (c == java.net.URISyntaxException.class)
- errorCode = CxnetConstants.URISYNTAX_EXCEPTION;
- th.printStackTrace();
- System.out.println("CxClient::start() A 2 errCode=" + errorCode);
- }
- m_listener.disconnected(errorCode);
- }
- }
- }
- });
- } catch (Exception e) {
- System.out.println("CxClient::start() excep B 1");
- e.printStackTrace();
- System.out.println("CxClient::start() excep B 2");
- m_listener.disconnected(CxnetConstants.UNKNOWN_EXCEPTION);
- }
- }//start()
- @Override
- protected void stopInThread(boolean releaseResOnly) {
- final Bootstrap bs = m_bootstrap;
- m_bootstrap = null;
- super.stopInThread(bs, releaseResOnly);
- }
- }//end cls - CxClient