有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Simple netty echo服务器不允许多个客户端同时连接

编辑:我删除了客户端代码,因为问题似乎出在服务器上

我实现了一个非常简单的netty echo服务器,与教程中建议的类似

问题是,当我试图运行指向同一服务器的多个客户端时,服务器似乎一次只允许一个连接。例如,当我运行“telnet localhost 8080”并尝试从两个不同的客户端使用echo服务器时,第一个客户端成功,而第二个客户端失败(不回复)。此外,当我启动多个netty客户端时,我在服务器端看到消息只从一个客户端端口接收——当该客户端完成并关闭其连接时,第二个客户端继续。有人知道为什么会这样吗?这是使用netty 3.5.1。同样值得注意的是,netstat在我的机器上运行得非常慢,尽管没有太多的输出。以下是我的服务器源代码(问题似乎出现在服务器上,因为我可以用telnet重现问题):

服务器:

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

public class Server {
    public static void main(String[] args) {

        ChannelFactory factory =
                new NioServerSocketChannelFactory(
                        Executors.newSingleThreadExecutor(),
                        Executors.newSingleThreadExecutor());

        ServerBootstrap bootstrap = new ServerBootstrap(factory);

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() {
                return Channels.pipeline(new EchoServerHandler());
            }
        });

        bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);
        bootstrap.bind(new InetSocketAddress(8080));
    }

    private static AtomicInteger count = new AtomicInteger(0);

    public static class EchoServerHandler extends SimpleChannelHandler {

        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
            Channel ch = e.getChannel();
            int t = count.incrementAndGet();
            if (t % 1000 == 0) {
                System.out.println("server " + t + " " + e.getChannel());
            }
            ch.write(e.getMessage());
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
            e.getCause().printStackTrace();
            Channel ch = e.getChannel();
            ch.close();
        }
    }
}

更新:似乎我只能在服务器上运行尽可能多的工作线程的客户机(通过一些使用不同数量的客户机和不同固定工作线程池大小的实验)。下面是一个工作线程的jstack,卡在epollWait上(有人知道为什么吗?):

"New I/O  worker #1" prio=10 tid=0x00007fdba801a000 nid=0x2b84 runnable [0x00007fdc296c2000]
   java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
    at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:228)
    at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:81)
    at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
    - locked <0x00000006b11732b0> (a sun.nio.ch.Util$2)
    - locked <0x00000006b11732a0> (a java.util.Collections$UnmodifiableSet)
    - locked <0x00000006b1173080> (a sun.nio.ch.EPollSelectorImpl)
    at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
    at org.jboss.netty.channel.socket.nio.SelectorUtil.select(SelectorUtil.java:52)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:209)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102)
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

共 (0) 个答案