Java Solaris NIO OP_CONNECT проблема

У меня есть клиент Java, который подключается к серверу C ++ с помощью сокетов TCP с использованием Java NIO. Это работает в Linux, AIX и HP / UX, но в Solaris событие OP_CONNECT никогда не срабатывает.

Дополнительные сведения:

  • Selector.select () возвращает 0, а «выбранный набор ключей» пуст.
  • Проблема возникает только при подключении к локальному компьютеру (через шлейф или интерфейс Ethernet. ), но работает при подключении к удаленному компьютеру.
  • Я подтвердил проблему на двух разных машинах Solaris 10; физический SPARC и виртуальный x64 (VMWare) с использованием обеих версий JDK 1.6.0_21 и _26.

Вот тестовый код, демонстрирующий проблему:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class NioTest3
{
    public static void main(String[] args)
    {
        int i, tcount = 1, open = 0;
        String[] addr = args[0].split(":");
        int port = Integer.parseInt(addr[1]);
        if (args.length == 2)
            tcount = Integer.parseInt(args[1]);
        InetSocketAddress inetaddr = new InetSocketAddress(addr[0], port);
        try
        {
            Selector selector = Selector.open();
            SocketChannel channel;
            for (i = 0; i < tcount; i++)
            {
                channel = SocketChannel.open();
                channel.configureBlocking(false);
                channel.register(selector, SelectionKey.OP_CONNECT);
                channel.connect(inetaddr);
            }
            open = tcount;
            while (open > 0)
            {
                int selected = selector.select();
                System.out.println("Selected=" + selected);
                Iterator it = selector.selectedKeys().iterator();
                while (it.hasNext())
                {
                    SelectionKey key = it.next();
                    it.remove();
                    channel = (SocketChannel)key.channel();
                    if (key.isConnectable())
                    {
                        System.out.println("isConnectable");
                        if (channel.finishConnect())
                        {
                            System.out.println(formatAddr(channel) + " connected");
                            key.interestOps(SelectionKey.OP_WRITE);
                        }
                    }
                    else if (key.isWritable())
                    {
                        System.out.println(formatAddr(channel) + " isWritable");
                        String message = formatAddr(channel) + " the quick brown fox jumps over the lazy dog";
                        ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
                        channel.write(buffer);
                        key.interestOps(SelectionKey.OP_READ);
                    }
                    else if (key.isReadable())
                    {
                        System.out.println(formatAddr(channel) + " isReadable");
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        channel.read(buffer);
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        String message = new String(bytes);
                        System.out.println(formatAddr(channel) + " read: '" + message + "'");
                        channel.close();
                        open--;
                    }
                }
            }

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

    static String formatAddr(SocketChannel channel)
    {
        return Integer.toString(channel.socket().getLocalPort());
    }
}

Вы можете запустить это с помощью командной строки:

java -cp . NioTest3 : 

Где порт должен быть 7, если вы работаете с реальным эхо-сервисом; то есть: [

java -cp . NioTest3 127.0.0.1:7 5

] Если вы не можете запустить реальную службу эха, то источник для одного - здесь . Скомпилируйте эхо-сервер под Solaris с помощью:

$ cc -o echoserver echoserver.c -lsocket -lnsl

и запустите его следующим образом:

$ ./echoserver 8007 > out 2>&1 &

Об этом было сообщено Sun как об ошибке .

5
задан 18 revs 9 July 2011 в 09:02
поделиться