package org.nutz.net;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.nutz.lang.Lang;
import org.nutz.log.Log;
import org.nutz.log.Logs;
/**
* 提供一个简易的 TCP 的 socket 监听服务器
*
* @author zozoh(zozohtnt@gmail.com)
*/
public class TcpServer implements Runnable {
private static final Log log = Logs.get();
private boolean stop;
private int port;
private ServerSocket listener;
private SocketHandler handler;
public TcpServer(int port, SocketHandler handler) {
this.port = port;
this.handler = handler;
}
protected void listen(Socket socket) {
SocketHandler handler = getHandler();
// 处理请求
try {
handler.handle(socket);
}
// 仅仅是关闭连接
catch (SocketClosed e) {}
// 停止服务
catch (ServerStopped e) {
stop = true;
}
// 处理异常
catch (Throwable e) {
handler.whenError(socket, e);
}
// 确保关闭
finally {
if (!socket.isClosed())
try {
socket.close();
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
}
public void run() {
// ----------------------------------------- 建立
log.infof("start TcpServer [%s] @ %d", Thread.currentThread().getName(), port);
try {
listener = new ServerSocket(port);
}
catch (IOException e1) {
throw Lang.wrapThrow(e1);
}
// ----------------------------------------- 循环
log.infof("TcpServer listen @ %d", port);
while (!stop) {
log.info("before accept ...");
Socket socket = null;
try {
socket = listener.accept();
}
catch (IOException e) {
log.fatalf("Fail to accept %s @ %d , System.exit!", Thread.currentThread()
.getName(), port);
System.exit(0);
}
log.info("do listen ...");
listen(socket);
log.infof("done for listen [%s:%d], stop=%b",
socket.getInetAddress().getHostName(),
socket.getPort(),
stop);
}
// ----------------------------------------- 关闭
try {
listener.close();
log.infof("TcpServer shutdown @ %d", port);
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
public SocketHandler getHandler() {
return handler;
}
public void setHandler(SocketHandler handler) {
this.handler = handler;
}
public void stop() {
stop = true;
}
}