错误在于:当你的代码在执行完while(!stop)之后,而没有执行accept之前,如果执行了quit,那么可想而知,你的socket将会被关闭,尽管这是stop被置成true,但是已经过了循环检测语句,所以在你执行accept的时候程序将爆出异常socket closed!你可以考虑不需要在quit的时候close.对,是这样子的。
public void quit(){
stop=true;
//这里给serverSocket发一个临时的连接请求
......
//
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
serverSocket.close();
}
public void quit(){
stop=true;
//这里给serverSocket发一个临时的连接请求
......
//
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
serverSocket.close();
}
解决方案 »
- AudioClip 问题求助
- StringBuffer转成String类型输出有优势吗
- 我在同一个package里定义了两个application Window,分别是s和a。我现在在s中定义一个按钮,想点击这个按钮后,a就显示,是怎么弄的啊,谢谢
- JAVA打开文件对话框怎么实现
- 如何将rtf里文本读取出来
- unreachable statement ??
- 各位大侠帮忙一下哈!!!小问题※
- java.sql.Statement 的批处理问题
- (急)一个currentThread()的问题,大侠指点!!
- 很菜的问题:jbuilder中的applet调试问题,在线等待,谢谢!
- 关于String编码问题(ISO-8859-1)
- 100分~求这个Layout类源!!
private boolean stop=false;
private ServerSocket serverSocket = new ServerSocket(......);
public void run(){
while(!stop){
try{
Socket socket=serverSocket.accept();//这里会抛出异常
}catch(Excetion e){
break;
}
new ClientThread(socket).start;
//ClientThread是一个线程类,处理socket,并包含了socket.close()
//注意:这里是ServerSocket,在serverSocket.close()时会有异常
//请不要与socket.close()混淆
}
PoolManager,SafeBufferedReader分别是连接池管理器和安全读入器。/**
* The server to monitor all tasks which comes from all client-side in LAN.
*
* @version $version 1.0
* @author <a href="mailto:[email protected]" ><b>[email protected]</b></a>
*/import java.util.ArrayList;
import java.util.StringTokenizer;import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;import java.net.InetAddress;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.SocketTimeoutException;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;import seu.yuch.sql.PoolManager;
import seu.yuch.Constants;public class TaskMonitorServer extends Thread
implements Constants
{
private int port = DEFAULT_PORT; //initialize port
private int timeout = DEFAULT_TIMEOUT; //timeout private PoolManager pools = null; /**
* Constructor.
*
*/
public TaskMonitorServer() {
this( DEFAULT_PORT,DEFAULT_TIMEOUT );
} /**
* Constructor.
*
* @param port int.
* @param timeout long.
*/
public TaskMonitorServer( int port,int timeout ) {
this.port = port;
this.timeout = timeout;
} /**
* Sets the interval.
*
* @param interval long.
*/
public void setTimeOut( int timeout ) {
this.timeout = timeout;
} /**
* Sets the port.
*
* @param port int.
*/
public void setPort( int port ) {
this.port = port;
}
/**
* Set connection pool manager
*
* @param PoolManager
*/
public void setPoolManager( PoolManager pools ) {
this.pools = pools;
} /**
* Get connection pool manager.
*
* @return PoolManager.
*/
public PoolManager getPoolManager() {
return this.pools;
}
/**
* Close server and dispose all resources
*
*/
public void release() {
if( pools != null ) {
pools.release();
}
} /**
* Starts to run server.
*
*/
public void run() {
try
{
ServerSocket server = new ServerSocket( port );
server.setSoTimeout( timeout );
while( true ) {
Socket listen = null;
try
{
listen = server.accept();
ProcessConnectionThread cc =
new ProcessConnectionThread( listen );
}
catch ( IOException e )
{
System.out.println( "无法监听到来的客户连接!" );
}
}
}
catch ( SocketTimeoutException e )
{
System.out.println( "服务器Socket超时!" );
if( pools != null ) {//close all connection in pool
pools.release();
}
return;
}
catch ( IOException e ) {
System.out.println( "Starting server thread error!!" );
if( pools != null ) {//close all connection in pool
pools.release();
}
return;
}
} /**
* Thread to process the activity information coming from client sides.
*
*/
class ProcessConnectionThread extends Thread {
private Socket client = null;
private SafeBufferedReader is = null;
public ProcessConnectionThread( Socket s ) { // constructor
client = s;
try {
is = new SafeBufferedReader( new BufferedReader(
new InputStreamReader( client.getInputStream() ) ) );
} catch ( IOException e ) {
System.out.println( "读取客户端资料异常: " + e.getMessage() );
}
this.start(); // Thread starts here...this start() will call run()
}
public void run() {
Connection conn = null;
Statement st = null;
try {
conn = pools.getConnection( "sqlserver" );
st = conn.createStatement(); InetAddress inet = client.getInetAddress();
String ip = inet.toString().substring(1); //clinet side's IP String activity = is.readLine(); //a activity item
while( activity != null ) {
//write a item about client's activity information into database
StringTokenizer items = new StringTokenizer( activity,"***" );
ArrayList infos = new ArrayList();
while( items.hasMoreTokens() ) {
infos.add( items.nextToken() );
}
StringBuffer buffer = new StringBuffer( "insert into" );
if( ((String)infos.get(1)).equalsIgnoreCase("CPU") ) {
String usage = (String)infos.get(2);
buffer.append( " client_cpu values(\'" + ip + "\'"
+ ",\'" + (String)infos.get(0) + "\'"
+ ",\'" + ( Integer.valueOf(usage.trim()).intValue() ) + "\')" );
}
else if( ((String)infos.get(1)).equalsIgnoreCase("NET") ) {
buffer.append(
" client_net values(\'" + ip + "\'"
+ ",\'" + (String)infos.get(0) + "\'" );
String[] infoitems = ((String)infos.get(2)).split( "###" );
buffer.append( ",\'" + Integer.valueOf(infoitems[0].trim()).intValue() + "\'" );
buffer.append( ",\'" + infoitems[1] + "\'" );
buffer.append( ",\'" + infoitems[2] + "\'" );
buffer.append( ",\'" + Integer.valueOf(infoitems[3].trim()).intValue() + "\'" );
buffer.append( ",\'" + infoitems[4] + "\'" );
buffer.append( ",\'" + Integer.valueOf(infoitems[5].trim()).intValue() + "\'" );
buffer.append( ",\'" + Integer.valueOf(infoitems[6].trim()).intValue() + "\')" );
}
else {
buffer.append( " client_activity values(\'" + ip + "\'" );
buffer.append( ",\'" + (String)infos.get(0) + "\'" );
buffer.append( ",\'" + (String)infos.get(1) + "\'" );
buffer.append( ",\'" + (String)infos.get(2) + "\')" );
}
System.out.println( buffer.toString() );
st.execute( buffer.toString() );
//read next item
activity = is.readLine();
}
if( st != null ) {//closse statement
st.close();
}
if( conn != null ) {//return connection into pools
pools.freeConnection( "sqlserver",conn );
}
}
catch ( SQLException e ) {
System.out.println( "数据库操作异常: " + e.getMessage() );
}
catch ( IOException e ) {
System.out.println( client + " 断开连接!" + e.getMessage() );
}
}
}
/**
* Test this application server.
*
*/
public static void main( String args[] ) {
TaskMonitorServer server = new TaskMonitorServer();
server.setTimeOut( 0 );//infinite wait
PoolManager pools = PoolManager.getInstance();
server.setPoolManager( pools );
server.run();
}
}
package com.counsel.square.server.impls;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;import com.counsel.square.server.eventdomains.LifeCycleEventDomain;
import com.counsel.square.server.eventdomains.ServerEventDomain;
import com.counsel.square.server.helpers.LifeCycleHelper;
import com.counsel.square.server.interfaces.Command;
import com.counsel.square.server.interfaces.Event;
import com.counsel.square.server.interfaces.EventDispatcher;
import com.counsel.square.server.interfaces.EventDomain;
import com.counsel.square.server.interfaces.EventSource;
import com.counsel.square.server.interfaces.KeySpace;
import com.counsel.square.server.interfaces.LifeCycle;
import com.counsel.square.server.interfaces.Server;
import com.counsel.square.server.utils.StackTraceUtils;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class ServerImpl implements Server { private Thread serviceThread; private boolean isStarted = false; private String name; private EventDispatcher serverEventDispatcher; private Selector selector; private int servicePort; private ServerSocketChannel ssc; private LinkedQueue commandQueue;
private LifeCycleHelper lcHelper; public ServerImpl(String name, int servicePort, LifeCycle life) {
this.name = name;
this.servicePort = servicePort;
init();
cradleFrom(life);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Server#init()
*/
private void init() {
serviceThread = new Thread(new Runnable() {
public void run() {
runService();
}
});
serviceThread.setPriority(Thread.MIN_PRIORITY + 1);
this.serverEventDispatcher = ServerEventDispatcher.getInstance();
commandQueue = new LinkedQueue();
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Server#startServer()
*/
public void startServer() throws IOException {
if (!isStarted) {
try {
Event event = new ServerEvent(this, null, new EventChannelImpl(
ServerEventDomain.DOMAIN, ServerEventDomain.SERVER_EVENT_START));
serverEventDispatcher.syncFireOnEventToSequence(event);
initServer();
isStarted = true;
serviceThread.start();
Event pevent = new ServerEvent(this, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_POSTSTART));
serverEventDispatcher.syncFireOnEventToSequence(pevent);
} catch (Throwable e1) {
ErrorEventSource source = new ErrorEventSource(this, e1);
Event event = new ServerEvent(source, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ERROR));
try {
serverEventDispatcher.asyncFireOnEventToSequence(event);
} catch (Throwable te) {
te.printStackTrace();
}
}
}
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Server#stopServer()
*/
public void stopServer() {
isStarted = false;
//to grave.
String[] info = StackTraceUtils.getCallerInditity();
if (!"grave".equals(info[1])) {//not called from grave.
this.grave();
}
//fire onStop event here.
Event event = new ServerEvent(this, null, new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_STOP));
try {
serverEventDispatcher.syncFireOnEventToSequence(event);
} catch (InterruptedException e) {
e.printStackTrace();
}
//serviceThread.interrupt();//or call wakeup method on selector?
selector.wakeup(); //do clear job here
clearResource(); //post stop event here.
Event pevent = new ServerEvent(this, null, new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_POSTSTOP));
try {
serverEventDispatcher.syncFireOnEventToSequence(pevent);
} catch (InterruptedException e) {
e.printStackTrace();
}
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Server#getServerName()
*/
public String getServerName() {
return this.name;
} protected void runService() {
while (isStarted) {
int i = 0;
try {
i = selector.select();
} catch (Exception ex) {
//debug
ex.printStackTrace();
}
if (i != 0) {
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
processEvent(key);
}
}
/*
* //need this? if(serviceThread.isInterrupted() && !isStarted){
* stop and cast unexecuted commands. break; }
*/
//do commands here.
/*
* (important! the command should not block!!); to avoid block
* commands,you should never expose server references to an un- safe
* user code.User's should commit commands through a proxy,such as a
* KeySpace. or alternately we set a timeout.
*/
synchronized (commandQueue) {
Command c = null;
while (commandQueue.peek() != null) {
Object command = null;
try {
command = commandQueue.take();
} catch (InterruptedException e) {
//fire error event
EventSource source = new ErrorEventSource(this, e);
Event event = new ServerEvent(source, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ERROR));
try {
serverEventDispatcher.asyncFireOnEventToFork(event);
} catch (Throwable t) {
//should not happen.
t.printStackTrace();
}
}
if (command != null) {
try {
//each command.execute should return within 300ms.
TimeoutCommandWrap wrap = new TimeoutCommandWrap(
(Command) command, 300);
wrap.execute();
if (wrap.isTimeout()) {
// TODO do some log here.
}
} catch (Throwable ta) {
EventSource source = new ErrorEventSource(this, ta);
Event event = new ServerEvent(
source,
null,
new EventChannelImpl(
ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ERROR));
try {
serverEventDispatcher
.asyncFireOnEventToFork(event);
} catch (Throwable t) {
//should not happen.
t.printStackTrace();
}
}
}
}
}
}
}
private void initServer() throws IOException {
ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
InetSocketAddress addr = new InetSocketAddress(servicePort);
ServerSocket socket = ssc.socket();
socket.bind(addr);
selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
} private void processEvent(SelectionKey key) {
try {
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
Event accept = new ServerEvent(this, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ACCEPT));
serverEventDispatcher.syncFireOnEventToSequence(accept);
SocketChannel sc = ((ServerSocketChannel) key.channel())
.accept();
sc.configureBlocking(false);
//create a key space for key.
sc.register(selector, SelectionKey.OP_READ);
SelectionKey k = sc.keyFor(selector);
KeySpaceImpl ks = new KeySpaceImpl(k, this);
k.attach(ks);
//TODO change this source.should not expose serversocket.
Event accepted = new ServerEvent(ks, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ACCEPTED));
serverEventDispatcher.syncFireOnEventToSequence(accepted);
} else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
KeySpace ks = (KeySpace) key.attachment();
if (ks.getStatus() != KeySpaceImpl.STATE_READING
&& ks.getStatus() != KeySpaceImpl.STATE_DOWN) {
ks.setStatus(this, KeySpaceImpl.STATE_READING);
//perform read task.
new ServerReadCommand(ks).execute();
}
}
} catch (Throwable re) {//other exception
EventSource source = new ErrorEventSource(this, re);
Event event = new ServerEvent(source, null, new EventChannelImpl(
ServerEventDomain.DOMAIN, ServerEventDomain.SERVER_EVENT_ERROR));
try {
serverEventDispatcher.asyncFireOnEventToSequence(event);
} catch (Throwable ire) {
ire.printStackTrace();
}
}
} private void clearResource() {
if (selector.isOpen()) {
Iterator it = selector.keys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
if (key.isValid()) {
try {
key.channel().close();
} catch (IOException e1) {
//ignore.
}
}
}
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ssc.isOpen()) {
try {
ssc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//other clear jobs.
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Finalizable#addFinalizableTask(java.lang.Runnable)
*/
public void addFinalizableTask(Thread task) {
Runtime.getRuntime().addShutdownHook(task);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Finalizable#removeFinalizableTask(java.lang.Thread)
*/
public void removeFinalizableTask(Thread task) {
Runtime.getRuntime().removeShutdownHook(task);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.Server#acceptCommand(com.counsel.square.server.interfaces.Command)
*/
public void acceptCommand(Command command) {
if (command == null) {
return;
}
synchronized (commandQueue) {
try {
commandQueue.put(command);
} catch (InterruptedException e) {
EventSource source = new ErrorEventSource(this, e);
Event event = new ServerEvent(source, null,
new EventChannelImpl(ServerEventDomain.DOMAIN,
ServerEventDomain.SERVER_EVENT_ERROR));
try {
serverEventDispatcher.asyncFireOnEventToFork(event);
} catch (Throwable ire) {
ire.printStackTrace();
}
return;
}
}
selector.wakeup();
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.LifeCycle#cradleFrom(com.counsel.square.server.interfaces.LifeCycle)
*/
public void cradleFrom(LifeCycle alive) {
lcHelper = new LifeCycleHelper(this);
lcHelper.cradleFrom(alive);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.LifeCycle#grow(com.counsel.square.server.interfaces.LifeCycle)
*/
public void grow(LifeCycle alive) {
lcHelper.grow(alive);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.LifeCycle#cutOff(com.counsel.square.server.interfaces.LifeCycle)
*/
public void cutOff(LifeCycle alive) {
lcHelper.cutOff(alive);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.LifeCycle#grave()
*/
public void grave() {
lcHelper.grave();
if (this.isStarted) {
this.stopServer();
}
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.EventSource#dispatcherFor(EventDomain)
*/
public EventDispatcher dispatcherFor(EventDomain domain) {
if (ServerEventDomain.DOMAIN.equals(domain)) {
return serverEventDispatcher;
} else {
return lcHelper.dispatcherFor(domain);
}
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.EventListener#handleEvent(com.counsel.square.server.interfaces.Event)
*/
public void handleEvent(Event event) {
lcHelper.handleEvent(event);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.EventSource#eventDomains()
*/
public EventDomain[] eventDomains() {
return new EventDomain[] { ServerEventDomain.DOMAIN, LifeCycleEventDomain.DOMAIN };
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.EventListener#acceptableEventsInSourceDomain(com.counsel.square.server.interfaces.EventDomain)
*/
public int[] acceptableEventsInSourceDomain(EventDomain sourceDomain) {
return lcHelper.acceptableEventsInSourceDomain(sourceDomain);
} /*
* (non-Javadoc)
*
* @see com.counsel.square.server.interfaces.EventListener#acceptableEventSourceDomains()
*/
public EventDomain[] acceptableEventSourceDomains() {
return lcHelper.acceptableEventSourceDomains();
}
}
server接口:
package com.counsel.square.server.interfaces;import java.io.IOException;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface Server extends Finalizable,LifeCycle {
public void startServer()throws IOException;
public void stopServer();
public String getServerName();
public void acceptCommand(Command command);
}
LifeCycle接口:
package com.counsel.square.server.interfaces;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface LifeCycle extends EventSource,EventListener {
public void cradleFrom(LifeCycle alive);
public void grow(LifeCycle alive);
public void cutOff(LifeCycle alive);
public void grave();
}EventSource接口:
package com.counsel.square.server.interfaces;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface EventSource {
public EventDomain[] eventDomains();
public EventDispatcher dispatcherFor(EventDomain domain);
}
EventListener接口:
package com.counsel.square.server.interfaces;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface EventListener {
public void handleEvent(Event event);
public int[] acceptableEventsInSourceDomain(EventDomain sourceDomain);
public EventDomain[] acceptableEventSourceDomains();
}
EventDispatcher接口:
package com.counsel.square.server.interfaces;import com.counsel.square.server.exceptions.UnSupportedEventListenerException;/**
* @author 王橙森
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface EventDispatcher {
public void addListener(EventListener listener)throws InterruptedException;
public void addListener(EventListener listener , EventChannel channel)throws InterruptedException, UnSupportedEventListenerException;
public void removeListener(EventListener listener , EventChannel channel)throws InterruptedException;
public void removeListener(EventListener listener)throws InterruptedException;
public void syncFireOnEventToSequence(Event event)throws InterruptedException;
public void asyncFireOnEventToSequence(Event event) throws InterruptedException;
public void syncFireOnEventToFork(Event event)throws InterruptedException;
public void asyncFireOnEventToFork(Event event) throws InterruptedException;
}