日期:2014-05-20  浏览次数:20887 次

关于IPv6 socket连接不上的问题
在windows平台上,jdk1.5环境写了一对收发小程序。服务器端和客户端都是v4和v6的双栈。测试v4地址发消息没有问题,但是测试v6地址发送消息,抛异常:java.net.SocketExcetion:connect refused.
客户端代码
Java code

public class Client {
    Socket serverSocket;
    BufferedReader in;
    PrintWriter out;
    
    public Client()
    {
        try
        {
            serverSocket = new Socket("2001::822:d8", 5114);
            in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
            out = new PrintWriter(serverSocket.getOutputStream(),true);
            BufferedReader line = new BufferedReader(new InputStreamReader(System.in));
            
            out.println(line.readLine());
            line.close();
            out.close();
            in.close();
            serverSocket.close();
        }
        catch (IOException e)
        {
            System.err.println("Couldn't get I/O for " + "the connection to: taranis.");
            System.exit(1);
        }
    }
    
    public static void main(String[] args)
    {
        new Client();
    }
}



服务端代码
Java code

public class CDRReactor implements Runnable
{
    final Selector            selector;
    final ServerSocketChannel serverSocket;


    /**
     * 创建新的 CDRReactor 对象.
     *
     * @param port -- 监听端口
     *
     * @throws IOException -- DOCUMENT ME!
     */
    public CDRReactor(int port) throws IOException
    {
        selector     = Selector.open();
        serverSocket = ServerSocketChannel.open();
        serverSocket.socket().bind(new InetSocketAddress(port));
        serverSocket.configureBlocking(false);

        SelectionKey sk = serverSocket.register(selector,SelectionKey.OP_ACCEPT);


        ////
        sk.attach(new Acceptor());
    }

    /**
     * 事件运行循环
     */
    public void run()
    {
        while(true)
        {
            try
            {
                ////
                selector.select();

                Set      selected = selector.selectedKeys();
                Iterator it = selected.iterator();

                while(it.hasNext())
                {
                    dispatch((SelectionKey) it.next());
                }

                selected.clear();
            }
            catch(IOException e)
            {
//                logger.info("ex occur in reactor run");
            }
        }
    }


    /**
     * 分发事件
     *
     * @param k -- DOCUMENT ME!
     */
    void dispatch(SelectionKey k)
    {
        Runnable r = (Runnable) (k.attachment());

        if(r != null)
        {
            r.run();
        }
    }


    /**
     * DOCUMENT ME!
     *
     * @param args -- DOCUMENT ME!
     */
    public static void main(String[] args)
    {
        try
        {
            CDRReactor server = new CDRReactor(5114);

            server.run();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }


    class Acceptor implements Runnable
    {
        /**
         * 连接建立的处理
         */
        public void run()
        {

            try
            {
                SocketChannel c = serverSocket.accept();

                if(c != null)
                {
                    System.out.println("Recieved message.");
                }
            }
            catch(IOException ex)
            {
                ////
                ex.printStackTrace();
            }
        }
    }
}



------解决方案--------------------
ipv4和ipv6要分别用两个socket监听的,
你服务器代码只用了 InetSocketAddress 指定端口,估计只是监听了ipv4的本地端口。
------解决方案--------------------
我试了下你的代码,
Client连接改为 new Socket("::", 5114),可以连接。