jcreatorqijiashe 2008-12-29 12:50
浏览 488
已采纳

用Mina开发Socket服务器总有一些不可预知的奇怪现象?程序结束不了?!

最近在用 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线程池在发挥作用,应该是前者),这样理解没错吧?
  • 写回答

17条回答 默认 最新

  • pigo2004 2008-12-29 12:50
    关注

    mina 1.1.x版本貌似是 session.close();

    对应的方法定义是: CloseFuture close();

    mina 2.0更简单好用。不过我们不是直接用。是参考2.0做了些裁减。

    mina的性能没什么可担心的,成功案例有:openfire

    可以google一下:openfire connection manager

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(16条)

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况