最近在用 Java的Socket框架mina开发一个服务器端程序,服务器写完后,用mina的客户端API写了程序去连接服务器端,也连接成功了,但是发现每次客户端连接完成运行后 过1分钟客户端程序才结束! 经过调试发现代码已经执行了客户端代码的最后一行! 真是奇怪,客户端代码如下:
public class Client
{
private static final String HOSTNAME = "localhost";
private static final int PORT = 20000;public static void main( String[] args ) throws Throwable { SocketConnector connector = new SocketConnector(); // Configure the service. SocketConnectorConfig cfg = new SocketConnectorConfig(); cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); cfg.getFilterChain().addLast( "logger", new LoggingFilter() ); IoSession session; try { ConnectFuture future = connector.connect(new InetSocketAddress( HOSTNAME, PORT), new ClientSessionHandler("Hi hi :("), cfg); future.join(); session = future.getSession(); } catch (RuntimeIOException e) { System.err.println("Failed to connect."); e.printStackTrace(); } // wait until the summation is done session.getCloseFuture().join(); System.out.println(session,"### all done! !"); }
"### all done! !" 明明都已经打印出来了! 但是发现进程中还是有一个 javaw.exe! 而且用进程管理工具无法结束!,过了1分钟后,这个javaw.exe就没有了,发现eclipse的控制台红色结束按钮也变灰色了. 这些居然都是在最后一行代码执行完发生的? 感觉Java真是一个不稳定的东西~~
问题补充
多谢回复,我看2.0是M版本,好像下载上面写着 unstable,所以没有用,你用这个版本感觉稳定吗? 我刚才又试验了一下 quickServer,试验socket连接到达100个居然就Connnectin refused了? 好像根本没有使用 非阻塞队列. mina虽然有我刚才说的问题,但是他却能坚持到 1000个连接没有发生 Connnectin refused的错误,说明他还是利用了线程池重用了很多连接,我现在马上试试 mina2.0! 我用的是1.1.7,connector没有dispose方法,那个例子我也看到了
问题补充
还有你知道他的 httpserver怎么用吗? asyWeb合到mina里面了,我看了例子"httpserver",但是里面居然没有客户端调用示例.客户端怎么传递参数到http服务器也没有说明
问题补充
我试了一下2.0M果然可以. 但是服务器端好像不能自己设置连接池了? 下面的代码在2.0不能用,你们怎么用连接池的? 我的性能是要求一台服务器机器需要有1000个并发连接. 我现在服务器这样写不知道有没有问题:
ExecutorService executor = Executors.newFixedThreadPool(1000);IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.setHandler( new TimeServerHandler() ); acceptor.getSessionConfig().setReadBufferSize( 2048 ); acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ); acceptor.getFilterChain().addLast("executor", new ExecutorFilter(executor)); acceptor.getFilterChain().addLast( "logger", new LoggingFilter() ); acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); acceptor.bind( new InetSocketAddress(PORT) );</pre>
客户端很简单,就是模拟1000个并发连接:public static void main( String[] args ) throws Throwable
{
for(int i=0;i<1000;i++){
log.info("Enter run l..."+i);
new Thread(new ClientThread(i)).start();
}} </pre>
每个客户端代码是:public void run() {
// TODO Auto-generated method stub
log.info("#### thread :"+this.num+" Running...");
NioSocketConnector connector = new NioSocketConnector();
// Configure the service.connector.setConnectTimeoutMillis(CONNECT_TIMEOUT); connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); connector.getFilterChain().addLast( "logger", new LoggingFilter() ); connector.setHandler(new ClientSessionHandler(" hihi new!")); IoSession session; for (;;) { try { ConnectFuture future = connector.connect(new InetSocketAddress( HOSTNAME, PORT)); future.awaitUninterruptibly(); session = future.getSession(); break; } catch (Exception e) { System.err.println("Failed to connect."); e.printStackTrace(); } } // wait until the summation is done session.getCloseFuture().awaitUninterruptibly(); connector.dispose(); log.info("#### thread :"+this.num+" over ..."); }</pre>
不知道这样写是不是已经用了NIO特性和数量是1000的连接池了. 而且我发现客户端如果不用mina的API,直接用Socket API连接,服务器撑不到1000个,200多个就Connection refused了.
问题补充
刚才试验了一下,模拟1000个客户端连接,成功了931个,异常是:2008-12-28 02:18:06,968 ERROR (LoggingFilter.java:127) - EXCEPTION :
java.io.IOException: 您的主机中的软件放弃了一个已建立的连接。
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:25)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:233)
at sun.nio.ch.IOUtil.read(IOUtil.java:206)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:207)
at org.apache.mina.transport.socket.nio.NioProcessor.read(NioProcessor.java:180)
at org.apache.mina.transport.socket.nio.NioProcessor.read(NioProcessor.java:42)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:568)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:547)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:539)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:57)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:867)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:65)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
不知道调整哪些参数可以不发生这个错误? 就是说调整什么可以使1000个连接都能连上
问题补充
windows需要修改OS的一个设置,但是设置了也不起作用,我再试试吧! java的NIO的目的是使服务器端打开尽量少的Socket连接,能处理尽可能多的客户端请求(不知道主要是非阻塞队列起作用还是那个concurrent线程池在发挥作用,应该是前者),这样理解没错吧?