Package com.google.code.hs4j.network.nio

Source Code of com.google.code.hs4j.network.nio.TCPController

/**
*Copyright [2008-2009] [dennis zhuang]
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*             http://www.apache.org/licenses/LICENSE-2.0
*Unless required by applicable law or agreed to in writing,
*software distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
*either express or implied. See the License for the specific language governing permissions and limitations under the License
*/

package com.google.code.hs4j.network.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

import com.google.code.hs4j.network.config.Configuration;
import com.google.code.hs4j.network.core.CodecFactory;
import com.google.code.hs4j.network.core.EventType;
import com.google.code.hs4j.network.core.Handler;
import com.google.code.hs4j.network.core.Session;
import com.google.code.hs4j.network.core.impl.StandardSocketOption;
import com.google.code.hs4j.network.nio.impl.SocketChannelController;

/**
* Controller for tcp server
*
* @author dennis
*/
public class TCPController extends SocketChannelController
     {

  private ServerSocketChannel serverSocketChannel;

  /**
   * Accept backlog queue size
   */
  private int backlog = 500; // default 500

  public int getBacklog() {
    return this.backlog;
  }

  public void setBacklog(int backlog) {
    if (isStarted()) {
      throw new IllegalStateException();
    }
    if (backlog < 0) {
      throw new IllegalArgumentException("backlog<0");
    }
    this.backlog = backlog;
  }

  public TCPController() {
    super();
  }

  public TCPController(Configuration configuration) {
    super(configuration, null, null);

  }

  public TCPController(Configuration configuration, CodecFactory codecFactory) {
    super(configuration, null, codecFactory);
  }

  public TCPController(Configuration configuration, Handler handler,
      CodecFactory codecFactory) {
    super(configuration, handler, codecFactory);
  }

  private int connectionTime, latency, bandwidth;

  public void setPerformancePreferences(int connectionTime, int latency,
      int bandwidth) {
    this.connectionTime = connectionTime;
    this.latency = latency;
    this.bandwidth = bandwidth;
  }

  @Override
  protected void doStart() throws IOException {
    this.serverSocketChannel = ServerSocketChannel.open();
    this.serverSocketChannel.socket().setSoTimeout(this.soTimeout);
    if (this.connectionTime != 0 || this.latency != 0
        || this.bandwidth != 0) {
      this.serverSocketChannel.socket().setPerformancePreferences(
          this.connectionTime, this.latency, this.bandwidth);
    }
    this.serverSocketChannel.configureBlocking(false);

    if (this.socketOptions.get(StandardSocketOption.SO_REUSEADDR) != null) {
      this.serverSocketChannel.socket().setReuseAddress(
          StandardSocketOption.SO_REUSEADDR.type().cast(
              this.socketOptions
                  .get(StandardSocketOption.SO_REUSEADDR)));
    }
    if (this.socketOptions.get(StandardSocketOption.SO_RCVBUF) != null) {
      this.serverSocketChannel.socket().setReceiveBufferSize(
          StandardSocketOption.SO_RCVBUF.type().cast(
              this.socketOptions
                  .get(StandardSocketOption.SO_RCVBUF)));

    }
    if (this.localSocketAddress != null) {
      this.serverSocketChannel.socket().bind(this.localSocketAddress,
          this.backlog);
    } else {
      this.serverSocketChannel.socket().bind(
          new InetSocketAddress("localhost", 0), this.backlog);
    }
    setLocalSocketAddress((InetSocketAddress) this.serverSocketChannel
        .socket().getLocalSocketAddress());
    this.selectorManager.registerChannel(this.serverSocketChannel,
        SelectionKey.OP_ACCEPT, null);
  }

  @Override
  public void onAccept(SelectionKey selectionKey) throws IOException {
    // �������رգ�ȡ������
    if (!this.serverSocketChannel.isOpen()) {
      selectionKey.cancel();
      return;
    }
    SocketChannel sc = null;
    try {
      sc = this.serverSocketChannel.accept();
      if (sc != null) {
        configureSocketChannel(sc);
        Session session = buildSession(sc);
        // enable read
        this.selectorManager.registerSession(session,
            EventType.ENABLE_READ);
        session.start();
        super.onAccept(selectionKey); // for statistics
      } else {
        log.debug("Accept fail");
      }
    } catch (IOException e) {
      closeAcceptChannel(selectionKey, sc);
      log.error("Accept connection error", e);
      notifyException(e);
    }
  }

  /**
   *
   * @param sk
   * @param sc
   * @throws IOException
   * @throws SocketException
   */
  private void closeAcceptChannel(SelectionKey sk, SocketChannel sc)
      throws IOException, SocketException {
    if (sk != null) {
      sk.cancel();
    }
    if (sc != null) {
      sc.socket().setSoLinger(true, 0); // await TIME_WAIT status
      sc.socket().shutdownOutput();
      sc.close();
    }
  }

  public void closeChannel(Selector selector) throws IOException {
    if (this.serverSocketChannel != null) {
      this.serverSocketChannel.close();
    }
  }

  public void unbind() throws IOException {
    stop();
  }

}
TOP

Related Classes of com.google.code.hs4j.network.nio.TCPController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.