com.google.code.yanf4j.nio.TCPController Maven / Gradle / Ivy
/**
*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.yanf4j.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.yanf4j.config.Configuration;
import com.google.code.yanf4j.core.CodecFactory;
import com.google.code.yanf4j.core.EventType;
import com.google.code.yanf4j.core.Handler;
import com.google.code.yanf4j.core.Session;
import com.google.code.yanf4j.core.impl.StandardSocketOption;
import com.google.code.yanf4j.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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy