PageRenderTime 63ms CodeModel.GetById 3ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 1ms

/src/org/zeromq/ZMQ.java

https://github.com/tfishwick/jzmq
Java | 1895 lines | 695 code | 251 blank | 949 comment | 87 complexity | 6ec720a53585c2ed38bfe9da2f3496e2 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2  Copyright (c) 2007-2010 iMatix Corporation
   3
   4  This file is part of 0MQ.
   5
   6  0MQ is free software; you can redistribute it and/or modify it under
   7  the terms of the Lesser GNU General Public License as published by
   8  the Free Software Foundation; either version 3 of the License, or
   9  (at your option) any later version.
  10
  11  0MQ is distributed in the hope that it will be useful,
  12  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  Lesser GNU General Public License for more details.
  15
  16  You should have received a copy of the Lesser GNU General Public License
  17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19package org.zeromq;
  20
  21import java.io.Closeable;
  22import java.nio.ByteBuffer;
  23import java.nio.channels.SelectableChannel;
  24import java.util.LinkedList;
  25import java.util.Random;
  26import java.util.concurrent.atomic.AtomicBoolean;
  27
  28/**
  29 * ZeroMQ JNI Bindings.
  30 * 
  31 * @author Gonzalo Diethelm
  32 * 
  33 */
  34public class ZMQ {
  35
  36    static {
  37        // if no embedded native library, revert to loading from java.library.path
  38        if (!EmbeddedLibraryTools.LOADED_EMBEDDED_LIBRARY)
  39            System.loadLibrary("jzmq");
  40    }
  41
  42    // Values for flags in Socket's send and recv functions.
  43    /**
  44     * Socket flag to indicate a nonblocking send or recv mode.
  45     */
  46    public static final int NOBLOCK = 1;
  47    public static final int DONTWAIT = 1;
  48    /**
  49     * Socket flag to indicate that more message parts are coming.
  50     */
  51    public static final int SNDMORE = 2;
  52
  53    // Socket types, used when creating a Socket.
  54    /**
  55     * Flag to specify a exclusive pair of items.
  56     */
  57    public static final int PAIR = 0;
  58    /**
  59     * Flag to specify a PUB socket, receiving side must be a SUB or XSUB.
  60     */
  61    public static final int PUB = 1;
  62    /**
  63     * Flag to specify the receiving part of the PUB or XPUB socket.
  64     */
  65    public static final int SUB = 2;
  66    /**
  67     * Flag to specify a REQ socket, receiving side must be a REP.
  68     */
  69    public static final int REQ = 3;
  70    /**
  71     * Flag to specify the receiving part of a REQ socket.
  72     */
  73    public static final int REP = 4;
  74    /**
  75     * Flag to specify a DEALER socket (aka XREQ). DEALER is really a combined ventilator / sink that does
  76     * load-balancing on output and fair-queuing on input with no other semantics. It is the only socket type that lets
  77     * you shuffle messages out to N nodes and shuffle the replies back, in a raw bidirectional asynch pattern.
  78     */
  79    public static final int DEALER = 5;
  80    /**
  81     * Old alias for DEALER flag. Flag to specify a XREQ socket, receiving side must be a XREP.
  82     * 
  83     * @deprecated As of release 3.0 of zeromq, replaced by {@link #DEALER}
  84     */
  85    public static final int XREQ = DEALER;
  86    /**
  87     * Flag to specify ROUTER socket (aka XREP). ROUTER is the socket that creates and consumes request-reply routing
  88     * envelopes. It is the only socket type that lets you route messages to specific connections if you know their
  89     * identities.
  90     */
  91    public static final int ROUTER = 6;
  92    /**
  93     * Old alias for ROUTER flag. Flag to specify the receiving part of a XREQ socket.
  94     * 
  95     * @deprecated As of release 3.0 of zeromq, replaced by {@link #ROUTER}
  96     */
  97    public static final int XREP = ROUTER;
  98    /**
  99     * Flag to specify the receiving part of a PUSH socket.
 100     */
 101    public static final int PULL = 7;
 102    /**
 103     * Flag to specify a PUSH socket, receiving side must be a PULL.
 104     */
 105    public static final int PUSH = 8;
 106    /**
 107     * Flag to specify a XPUB socket, receiving side must be a SUB or XSUB. Subscriptions can be received as a message.
 108     * Subscriptions start with a '1' byte. Unsubscriptions start with a '0' byte.
 109     */
 110    public static final int XPUB = 9;
 111    /**
 112     * Flag to specify the receiving part of the PUB or XPUB socket. Allows
 113     */
 114    public static final int XSUB = 10;
 115
 116    /**
 117     * Flag to specify a STREAMER device.
 118     */
 119    public static final int STREAMER = 1;
 120
 121    /**
 122     * Flag to specify a FORWARDER device.
 123     */
 124    public static final int FORWARDER = 2;
 125
 126    /**
 127     * Flag to specify a QUEUE device.
 128     */
 129    public static final int QUEUE = 3;
 130
 131    /**
 132     * @see ZMQ#PULL
 133     */
 134    @Deprecated
 135    public static final int UPSTREAM = PULL;
 136    /**
 137     * @see ZMQ#PUSH
 138     */
 139    @Deprecated
 140    public static final int DOWNSTREAM = PUSH;
 141
 142    /**
 143     * @return Major version number of the ZMQ library.
 144     */
 145    public static int getMajorVersion() {
 146        return version_major();
 147    }
 148
 149    /**
 150     * @return Major version number of the ZMQ library.
 151     */
 152    public static int getMinorVersion() {
 153        return version_minor();
 154    }
 155
 156    /**
 157     * @return Major version number of the ZMQ library.
 158     */
 159    public static int getPatchVersion() {
 160        return version_patch();
 161    }
 162
 163    /**
 164     * @return Full version number of the ZMQ library used for comparing versions.
 165     */
 166    public static int getFullVersion() {
 167        return version_full();
 168    }
 169
 170    /**
 171     * @param major Version major component.
 172     * @param minor Version minor component.
 173     * @param patch Version patch component.
 174     * 
 175     * @return Comparible single int version number.
 176     */
 177    public static int makeVersion(final int major, final int minor, final int patch) {
 178        return make_version(major, minor, patch);
 179    }
 180
 181    /**
 182     * @return String version number in the form major.minor.patch.
 183     */
 184    public static String getVersionString() {
 185        return String.format("%d.%d.%d", version_major(), version_minor(), version_patch());
 186    }
 187
 188    /**
 189     * Starts the built-in 0MQ proxy in the current application thread. The proxy connects a frontend socket to a
 190     * backend socket. Conceptually, data flows from frontend to backend. Depending on the socket types, replies may
 191     * flow in the opposite direction. The direction is conceptual only; the proxy is fully symmetric and there is no
 192     * technical difference between frontend and backend.
 193     * 
 194     * Before calling ZMQ.proxy() you must set any socket options, and connect or bind both frontend and backend
 195     * sockets. The two conventional proxy models are:
 196     * 
 197     * ZMQ.proxy() runs in the current thread and returns only if/when the current context is closed.
 198     * 
 199     * @param frontend ZMQ.Socket
 200     * @param backend ZMQ.Socket
 201     * @param capture If the capture socket is not NULL, the proxy shall send all messages, received on both frontend
 202     *            and backend, to the capture socket. The capture socket should be a ZMQ_PUB, ZMQ_DEALER, ZMQ_PUSH, or
 203     *            ZMQ_PAIR socket.
 204     * @since 3.2.2
 205     */
 206    public static void proxy(Socket frontend, Socket backend, Socket capture) {
 207        if (ZMQ.version_full() < ZMQ.make_version(3, 2, 2))
 208            throw new UnsupportedOperationException();
 209
 210        run_proxy(frontend, backend, capture);
 211    }
 212
 213    /**
 214     * Poll on polling items until timeout
 215     * 
 216     * @param items polling items
 217     * @param timeout timeout in millisecond
 218     * @return number of events
 219     */
 220    public static int poll(PollItem[] items, long timeout) {
 221
 222        return poll(items, items.length, timeout);
 223    }
 224
 225    /**
 226     * Poll on polling items until timeout
 227     * 
 228     * @param items polling items
 229     * @param count active item count
 230     * @param timeout timeout in millisecond
 231     * @return number of events
 232     */
 233    public static int poll(PollItem[] items, int count, long timeout) {
 234
 235        return Poller.run_poll(items, count, timeout);
 236    }
 237
 238    protected static native int version_full();
 239
 240    protected static native int version_major();
 241
 242    protected static native int version_minor();
 243
 244    protected static native int version_patch();
 245
 246    protected static native int make_version(int major, int minor, int patch);
 247
 248    protected static native long ENOTSUP();
 249
 250    protected static native long EPROTONOSUPPORT();
 251
 252    protected static native long ENOBUFS();
 253
 254    protected static native long ENETDOWN();
 255
 256    protected static native long EADDRINUSE();
 257
 258    protected static native long EADDRNOTAVAIL();
 259
 260    protected static native long ECONNREFUSED();
 261
 262    protected static native long EINPROGRESS();
 263
 264    protected static native long EHOSTUNREACH();
 265
 266    protected static native long EMTHREAD();
 267
 268    protected static native long EFSM();
 269
 270    protected static native long ENOCOMPATPROTO();
 271
 272    protected static native long ETERM();
 273
 274    protected static native long ENOTSOCK();
 275
 276    private static native void run_proxy(Socket frontend, Socket backend, Socket capture);
 277
 278    /**
 279     * Inner class: Error.
 280     */
 281    public enum Error {
 282
 283        ENOTSUP(ENOTSUP()),
 284
 285        EPROTONOSUPPORT(EPROTONOSUPPORT()),
 286
 287        ENOBUFS(ENOBUFS()),
 288
 289        ENETDOWN(ENETDOWN()),
 290
 291        EADDRINUSE(EADDRINUSE()),
 292
 293        EADDRNOTAVAIL(EADDRNOTAVAIL()),
 294
 295        ECONNREFUSED(ECONNREFUSED()),
 296
 297        EINPROGRESS(EINPROGRESS()),
 298
 299        EHOSTUNREACH(EHOSTUNREACH()),
 300
 301        EMTHREAD(EMTHREAD()),
 302
 303        EFSM(EFSM()),
 304
 305        ENOCOMPATPROTO(ENOCOMPATPROTO()),
 306
 307        ETERM(ETERM()),
 308
 309        ENOTSOCK(ENOTSOCK());
 310
 311        private final long code;
 312
 313        Error(long code) {
 314            this.code = code;
 315        }
 316
 317        public long getCode() {
 318            return code;
 319        }
 320
 321        public static Error findByCode(int code) {
 322            for (Error e : Error.class.getEnumConstants()) {
 323                if (e.getCode() == code) {
 324                    return e;
 325                }
 326            }
 327            throw new IllegalArgumentException("Unknown " + Error.class.getName() + " enum code:" + code);
 328        }
 329    }
 330
 331    /**
 332     * Create a new Context.
 333     * 
 334     * @param ioThreads Number of threads to use, usually 1 is sufficient for most use cases.
 335     * @return the Context
 336     */
 337    public static Context context(int ioThreads) {
 338        return new Context(ioThreads);
 339    }
 340
 341    /**
 342     * Inner class: Context.
 343     */
 344    public static class Context implements Closeable {
 345        private final AtomicBoolean closed = new AtomicBoolean(false);
 346
 347        /**
 348         * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ Context has been disposed
 349         * of.
 350         */
 351        public void term() {
 352            if(closed.compareAndSet(false, true)) {
 353                destroy();
 354            }
 355        }
 356
 357        /**
 358         * Create a new Socket within this context.
 359         * 
 360         * @param type the socket type.
 361         * @return the newly created Socket.
 362         */
 363        public Socket socket(int type) {
 364            return new Socket(this, type);
 365        }
 366
 367        /**
 368         * Create a new Poller within this context, with a default size.
 369         * 
 370         * @return the newly created Poller.
 371         * @deprecated use Poller constructor
 372         */
 373        public Poller poller() {
 374            return new Poller(this);
 375        }
 376
 377        /**
 378         * Create a new Poller within this context, with a specified initial size.
 379         * 
 380         * @param size the poller initial size.
 381         * @return the newly created Poller.
 382         * @deprecated use Poller constructor
 383         */
 384        public Poller poller(int size) {
 385            return new Poller(this, size);
 386        }
 387
 388        /**
 389         * Class constructor.
 390         * 
 391         * @param ioThreads size of the threads pool to handle I/O operations.
 392         */
 393        protected Context(int ioThreads) {
 394            construct(ioThreads);
 395        }
 396
 397        /** Initialize the JNI interface */
 398        protected native void construct(int ioThreads);
 399
 400        /** Free all resources used by JNI interface. */
 401        protected native void destroy();
 402
 403        /**
 404         * Get the underlying context handle. This is private because it is only accessed from JNI, where Java access
 405         * controls are ignored.
 406         * 
 407         * @return the internal 0MQ context handle.
 408         */
 409        private long getContextHandle() {
 410            return this.contextHandle;
 411        }
 412
 413        /** Opaque data used by JNI driver. */
 414        private long contextHandle;
 415
 416        public void close() {
 417            term();
 418        }
 419    }
 420
 421    /**
 422     * Inner class: Socket.
 423     */
 424    public static class Socket implements Closeable {
 425        private final AtomicBoolean closed = new AtomicBoolean(false);
 426        /**
 427         * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ Socket has been disposed
 428         * of.
 429         */
 430        public void close() {
 431            if(closed.compareAndSet(false, true)) {
 432                destroy();
 433            }
 434        }
 435
 436        /**
 437         * The 'ZMQ_TYPE option shall retrieve the socket type for the specified 'socket'. The socket type is specified
 438         * at socket creation time and cannot be modified afterwards.
 439         * 
 440         * @return the socket type.
 441         * @since 2.1.0
 442         */
 443        public int getType() {
 444            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
 445                return -1;
 446
 447            return (int) getLongSockopt(TYPE);
 448        }
 449
 450        /**
 451         * @see #setLinger(long)
 452         * 
 453         * @return the linger period.
 454         * @since 2.1.0
 455         */
 456        public long getLinger() {
 457            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
 458                return -1;
 459
 460            return getLongSockopt(LINGER);
 461        }
 462
 463        /**
 464         * @see #setReconnectIVL(long)
 465         * 
 466         * @return the reconnectIVL.
 467         * @since 3.0.0
 468         */
 469        public long getReconnectIVL() {
 470            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 10))
 471                return -1;
 472
 473            return getLongSockopt(RECONNECT_IVL);
 474        }
 475
 476        /**
 477         * @see #setBacklog(long)
 478         * 
 479         * @return the backlog.
 480         * @since 3.0.0
 481         */
 482        public long getBacklog() {
 483            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 484                return -1;
 485
 486            return getLongSockopt(BACKLOG);
 487        }
 488
 489        /**
 490         * @see #setReconnectIVLMax(long)
 491         * 
 492         * @return the reconnectIVLMax.
 493         * @since 3.0.0
 494         */
 495        public long getReconnectIVLMax() {
 496            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 10))
 497                return -1;
 498
 499            return getLongSockopt(RECONNECT_IVL_MAX);
 500        }
 501
 502        /**
 503         * @see #setMaxMsgSize(long)
 504         * 
 505         * @return the maxMsgSize.
 506         * @since 3.0.0
 507         */
 508        public long getMaxMsgSize() {
 509            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 510                return -1;
 511
 512            return getLongSockopt(MAXMSGSIZE);
 513        }
 514
 515        /**
 516         * @see #setSndHWM(long)
 517         * 
 518         * @return the SndHWM.
 519         * @since 3.0.0
 520         */
 521        public long getSndHWM() {
 522            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 523                return -1;
 524
 525            return getLongSockopt(SNDHWM);
 526        }
 527
 528        /**
 529         * @see #setRcvHWM(long)
 530         * 
 531         * @return the recvHWM period.
 532         * @since 3.0.0
 533         */
 534        public long getRcvHWM() {
 535            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 536                return -1;
 537
 538            return getLongSockopt(RCVHWM);
 539        }
 540
 541        /**
 542         * @see #setHWM(long)
 543         * 
 544         * @return the High Water Mark.
 545         */
 546        public long getHWM() {
 547            if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
 548                return -1;
 549
 550            return getLongSockopt(HWM);
 551        }
 552
 553        /**
 554         * @see #setSwap(long)
 555         * 
 556         * @return the number of messages to swap at most.
 557         */
 558        public long getSwap() {
 559            if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
 560                return -1;
 561
 562            return getLongSockopt(SWAP);
 563        }
 564
 565        /**
 566         * @see #setAffinity(long)
 567         * 
 568         * @return the affinity.
 569         */
 570        public long getAffinity() {
 571            return getLongSockopt(AFFINITY);
 572        }
 573
 574        /**
 575         * @see #setTCPKeepAlive(long)
 576         * 
 577         * @return the keep alive setting.
 578         */
 579        public long getTCPKeepAliveSetting() {
 580            if (ZMQ.version_full() < ZMQ.make_version(3, 2, 0))
 581                return -1;
 582
 583            return getLongSockopt(KEEPALIVE);
 584        }
 585
 586        /**
 587         * @see #setTCPKeepAliveIdle(long)
 588         * 
 589         * @return the keep alive idle value.
 590         */
 591        public long getTCPKeepAliveIdle() {
 592            if (ZMQ.version_full() < ZMQ.make_version(3, 2, 0))
 593                return -1;
 594
 595            return getLongSockopt(KEEPALIVEIDLE);
 596        }
 597
 598        /**
 599         * @see #setTCPKeepAliveInterval(long)
 600         * 
 601         * @return the keep alive interval.
 602         */
 603        public long getTCPKeepAliveInterval() {
 604            if (ZMQ.version_full() < ZMQ.make_version(3, 2, 0))
 605                return -1;
 606
 607            return getLongSockopt(KEEPALIVEINTVL);
 608        }
 609
 610        /**
 611         * @see #setTCPKeepAliveCount(long)
 612         * 
 613         * @return the keep alive count.
 614         */
 615        public long getTCPKeepAliveCount() {
 616            if (ZMQ.version_full() < ZMQ.make_version(3, 2, 0))
 617                return -1;
 618
 619            return getLongSockopt(KEEPALIVECNT);
 620        }
 621
 622        /**
 623         * @see #setIdentity(byte[])
 624         * 
 625         * @return the Identitiy.
 626         */
 627        public byte[] getIdentity() {
 628            return getBytesSockopt(IDENTITY);
 629        }
 630
 631        /**
 632         * @see #setRate(long)
 633         * 
 634         * @return the Rate.
 635         */
 636        public long getRate() {
 637            return getLongSockopt(RATE);
 638        }
 639
 640        /**
 641         * @see #setRecoveryInterval(long)
 642         * 
 643         * @return the RecoveryIntervall.
 644         */
 645        public long getRecoveryInterval() {
 646            return getLongSockopt(RECOVERY_IVL);
 647        }
 648
 649        /**
 650         * @see #setMulticastLoop(boolean)
 651         * 
 652         * @return the Multicast Loop.
 653         */
 654        public boolean hasMulticastLoop() {
 655            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 656                return false;
 657
 658            return getLongSockopt(MCAST_LOOP) != 0;
 659        }
 660
 661        /**
 662         * Sets the time-to-live field in every multicast packet sent from this socket. The default is 1 which means
 663         * that the multicast packets don't leave the local network.
 664         * 
 665         * @param mcast_hops
 666         */
 667        public void setMulticastHops(long mcast_hops) {
 668            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 669                return;
 670
 671            setLongSockopt(MULTICAST_HOPS, mcast_hops);
 672        }
 673
 674        /**
 675         * @see #setMulticastHops(long)
 676         * 
 677         * @return the Multicast Hops.
 678         */
 679        public long getMulticastHops() {
 680            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 681                return 1;
 682            return getLongSockopt(MULTICAST_HOPS);
 683        }
 684
 685        /**
 686         * Sets the timeout for receive operation on the socket. If the value is 0, recv will return immediately, with a
 687         * EAGAIN error if there is no message to receive. If the value is -1, it will block until a message is
 688         * available. For all other values, it will wait for a message for that amount of time before returning with an
 689         * EAGAIN error.
 690         * 
 691         * @param timeout Timeout for receive operation in milliseconds. Default -1 (infinite)
 692         */
 693        public void setReceiveTimeOut(int timeout) {
 694            if (ZMQ.version_full() < ZMQ.make_version(2, 2, 0))
 695                return;
 696
 697            setLongSockopt(RCVTIMEO, timeout);
 698        }
 699
 700        /**
 701         * @see #setReceiveTimeOut(long)
 702         * 
 703         * @return the Receive Timeout in milliseconds
 704         */
 705        public int getReceiveTimeOut() {
 706            if (ZMQ.version_full() < ZMQ.make_version(2, 2, 0))
 707                return -1;
 708            return (int) getLongSockopt(RCVTIMEO);
 709        }
 710
 711        /**
 712         * Sets the timeout for send operation on the socket. If the value is 0, send will return immediately, with a
 713         * EAGAIN error if the message cannot be sent. If the value is -1, it will block until the message is sent. For
 714         * all other values, it will try to send the message for that amount of time before returning with an EAGAIN
 715         * error.
 716         * 
 717         * @param timeout Timeout for send operation in milliseconds. Default -1 (infinite)
 718         */
 719        public void setSendTimeOut(int timeout) {
 720            if (ZMQ.version_full() < ZMQ.make_version(2, 2, 0))
 721                return;
 722
 723            setLongSockopt(SNDTIMEO, timeout);
 724        }
 725
 726        /**
 727         * @see #setSendTimeOut(long)
 728         * 
 729         * @return the Send Timeout. in milliseconds
 730         */
 731        public int getSendTimeOut() {
 732            if (ZMQ.version_full() < ZMQ.make_version(2, 2, 0))
 733                return -1;
 734            return (int) getLongSockopt(SNDTIMEO);
 735        }
 736
 737        /**
 738         * @see #setSendBufferSize(long)
 739         * 
 740         * @return the kernel send buffer size.
 741         */
 742        public long getSendBufferSize() {
 743            return getLongSockopt(SNDBUF);
 744        }
 745
 746        /**
 747         * @see #setReceiveBufferSize(long)
 748         * 
 749         * @return the kernel receive buffer size.
 750         */
 751        public long getReceiveBufferSize() {
 752            return getLongSockopt(RCVBUF);
 753        }
 754
 755        /**
 756         * @see #setIPv4only(long)
 757         * 
 758         * @return the IPv4 only socket.
 759         */
 760        public boolean getIPv4Only() {
 761            return getLongSockopt(IPV4ONLY) == 1;
 762        }
 763
 764        /**
 765         * The 'ZMQ_RCVMORE' option shall return a boolean value indicating if the multi-part message currently being
 766         * read from the specified 'socket' has more message parts to follow. If there are no message parts to follow or
 767         * if the message currently being read is not a multi-part message a value of zero shall be returned. Otherwise,
 768         * a value of 1 shall be returned.
 769         * 
 770         * @return true if there are more messages to receive.
 771         */
 772        public boolean hasReceiveMore() {
 773            return getLongSockopt(RCVMORE) != 0;
 774        }
 775
 776        /**
 777         * The 'ZMQ_FD' option shall retrieve file descriptor associated with the 0MQ socket. The descriptor can be used
 778         * to integrate 0MQ socket into an existing event loop. It should never be used for anything else than polling
 779         * -- such as reading or writing. The descriptor signals edge-triggered IN event when something has happened
 780         * within the 0MQ socket. It does not necessarily mean that the messages can be read or written. Check
 781         * ZMQ_EVENTS option to find out whether the 0MQ socket is readable or writeable.
 782         * 
 783         * @return the underlying file descriptor.
 784         * @since 2.1.0
 785         */
 786        public long getFD() {
 787            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
 788                return -1;
 789
 790            return getLongSockopt(FD);
 791        }
 792
 793        /**
 794         * The 'ZMQ_EVENTS' option shall retrieve event flags for the specified socket. If a message can be read from
 795         * the socket ZMQ_POLLIN flag is set. If message can be written to the socket ZMQ_POLLOUT flag is set.
 796         * 
 797         * @return the mask of outstanding events.
 798         * @since 2.1.0
 799         */
 800        public long getEvents() {
 801            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
 802                return -1;
 803
 804            return getLongSockopt(EVENTS);
 805        }
 806
 807        /**
 808         * The 'ZMQ_LINGER' option shall retrieve the period for pending outbound messages to linger in memory after
 809         * closing the socket. Value of -1 means infinite. Pending messages will be kept until they are fully
 810         * transferred to the peer. Value of 0 means that all the pending messages are dropped immediately when socket
 811         * is closed. Positive value means number of milliseconds to keep trying to send the pending messages before
 812         * discarding them.
 813         * 
 814         * @param linger the linger period.
 815         * @since 2.1.0
 816         */
 817        public void setLinger(long linger) {
 818            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
 819                return;
 820
 821            setLongSockopt(LINGER, linger);
 822        }
 823
 824        /**
 825         * @since 3.0.0
 826         */
 827        public void setReconnectIVL(long reconnectIVL) {
 828            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 10))
 829                return;
 830
 831            setLongSockopt(RECONNECT_IVL, reconnectIVL);
 832        }
 833
 834        /**
 835         * @since 3.0.0
 836         */
 837        public void setBacklog(long backlog) {
 838            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 839                return;
 840
 841            setLongSockopt(BACKLOG, backlog);
 842        }
 843
 844        /**
 845         * @since 3.0.0
 846         */
 847        public void setReconnectIVLMax(long reconnectIVLMax) {
 848            if (ZMQ.version_full() < ZMQ.make_version(2, 1, 10))
 849                return;
 850
 851            setLongSockopt(RECONNECT_IVL_MAX, reconnectIVLMax);
 852        }
 853
 854        /**
 855         * @since 3.0.0
 856         */
 857        public void setMaxMsgSize(long maxMsgSize) {
 858            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 859                return;
 860
 861            setLongSockopt(MAXMSGSIZE, maxMsgSize);
 862        }
 863
 864        /**
 865         * @since 3.0.0
 866         */
 867        public void setSndHWM(long sndHWM) {
 868            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 869                return;
 870
 871            setLongSockopt(SNDHWM, sndHWM);
 872        }
 873
 874        /**
 875         * @since 3.0.0
 876         */
 877        public void setRcvHWM(long rcvHWM) {
 878            if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
 879                return;
 880
 881            setLongSockopt(RCVHWM, rcvHWM);
 882        }
 883
 884        /**
 885         * The 'ZMQ_HWM' option shall set the high water mark for the specified 'socket'. The high water mark is a hard
 886         * limit on the maximum number of outstanding messages 0MQ shall queue in memory for any single peer that the
 887         * specified 'socket' is communicating with.
 888         * 
 889         * If this limit has been reached the socket shall enter an exceptional state and depending on the socket type,
 890         * 0MQ shall take appropriate action such as blocking or dropping sent messages. Refer to the individual socket
 891         * descriptions in the man page of zmq_socket[3] for details on the exact action taken for each socket type.
 892         * 
 893         * @param hwm the number of messages to queue.
 894         */
 895        public void setHWM(long hwm) {
 896            if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
 897                return;
 898
 899            setLongSockopt(HWM, hwm);
 900        }
 901
 902        /**
 903         * Get the Swap. The 'ZMQ_SWAP' option shall set the disk offload (swap) size for the specified 'socket'. A
 904         * socket which has 'ZMQ_SWAP' set to a non-zero value may exceed its high water mark; in this case outstanding
 905         * messages shall be offloaded to storage on disk rather than held in memory.
 906         * 
 907         * @param swap The value of 'ZMQ_SWAP' defines the maximum size of the swap space in bytes.
 908         */
 909        public void setSwap(long swap) {
 910            if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
 911                return;
 912
 913            setLongSockopt(SWAP, swap);
 914        }
 915
 916        /**
 917         * Get the Affinity. The 'ZMQ_AFFINITY' option shall set the I/O thread affinity for newly created connections
 918         * on the specified 'socket'.
 919         * 
 920         * Affinity determines which threads from the 0MQ I/O thread pool associated with the socket's _context_ shall
 921         * handle newly created connections. A value of zero specifies no affinity, meaning that work shall be
 922         * distributed fairly among all 0MQ I/O threads in the thread pool. For non-zero values, the lowest bit
 923         * corresponds to thread 1, second lowest bit to thread 2 and so on. For example, a value of 3 specifies that
 924         * subsequent connections on 'socket' shall be handled exclusively by I/O threads 1 and 2.
 925         * 
 926         * See also in the man page of zmq_init[3] for details on allocating the number of I/O threads for a specific
 927         * _context_.
 928         * 
 929         * @param affinity the affinity.
 930         */
 931        public void setAffinity(long affinity) {
 932            setLongSockopt(AFFINITY, affinity);
 933        }
 934
 935        /**
 936         * Override SO_KEEPALIVE socket option (where supported by OS) to enable keep-alive packets for a socket
 937         * connection. Possible values are -1, 0, 1. The default value -1 will skip all overrides and do the OS default.
 938         * 
 939         * @param optVal The value of 'ZMQ_TCP_KEEPALIVE' to turn TCP keepalives on (1) or off (0).
 940         */
 941        public void setTCPKeepAlive(long optVal) {
 942            if (ZMQ.version_full() >= ZMQ.make_version(3, 2, 0))
 943                setLongSockopt(KEEPALIVE, optVal);
 944        }
 945
 946        /**
 947         * Override TCP_KEEPCNT socket option (where supported by OS). The default value -1 will skip all overrides and
 948         * do the OS default.
 949         * 
 950         * @param optVal The value of 'ZMQ_TCP_KEEPALIVE_CNT' defines the number of keepalives before death.
 951         */
 952        public void setTCPKeepAliveCount(long optVal) {
 953            if (ZMQ.version_full() >= ZMQ.make_version(3, 2, 0))
 954                setLongSockopt(KEEPALIVECNT, optVal);
 955        }
 956
 957        /**
 958         * Override TCP_KEEPINTVL socket option (where supported by OS). The default value -1 will skip all overrides
 959         * and do the OS default.
 960         * 
 961         * @param optVal The value of 'ZMQ_TCP_KEEPALIVE_INTVL' defines the interval between keepalives. Unit is OS
 962         *            dependant.
 963         */
 964        public void setTCPKeepAliveInterval(long optVal) {
 965            if (ZMQ.version_full() >= ZMQ.make_version(3, 2, 0))
 966                setLongSockopt(KEEPALIVEINTVL, optVal);
 967        }
 968
 969        /**
 970         * Override TCP_KEEPCNT (or TCP_KEEPALIVE on some OS) socket option (where supported by OS). The default value
 971         * -1 will skip all overrides and do the OS default.
 972         * 
 973         * @param optVal The value of 'ZMQ_TCP_KEEPALIVE_IDLE' defines the interval between the last data packet sent
 974         *            over the socket and the first keepalive probe. Unit is OS dependant.
 975         */
 976        public void setTCPKeepAliveIdle(long optVal) {
 977            if (ZMQ.version_full() >= ZMQ.make_version(3, 2, 0))
 978                setLongSockopt(KEEPALIVEIDLE, optVal);
 979        }
 980
 981        /**
 982         * The 'ZMQ_IDENTITY' option shall set the identity of the specified 'socket'. Socket identity determines if
 983         * existing 0MQ infastructure (_message queues_, _forwarding devices_) shall be identified with a specific
 984         * application and persist across multiple runs of the application.
 985         * 
 986         * If the socket has no identity, each run of an application is completely separate from other runs. However,
 987         * with identity set the socket shall re-use any existing 0MQ infrastructure configured by the previous run(s).
 988         * Thus the application may receive messages that were sent in the meantime, _message queue_ limits shall be
 989         * shared with previous run(s) and so on.
 990         * 
 991         * Identity should be at least one byte and at most 255 bytes long. Identities starting with binary zero are
 992         * reserved for use by 0MQ infrastructure.
 993         * 
 994         * @param identity
 995         */
 996        public void setIdentity(byte[] identity) {
 997            setBytesSockopt(IDENTITY, identity);
 998        }
 999
1000        /**
1001         * The 'ZMQ_SUBSCRIBE' option shall establish a new message filter on a 'ZMQ_SUB' socket. Newly created
1002         * 'ZMQ_SUB' sockets shall filter out all incoming messages, therefore you should call this option to establish
1003         * an initial message filter.
1004         * 
1005         * An empty 'option_value' of length zero shall subscribe to all incoming messages. A non-empty 'option_value'
1006         * shall subscribe to all messages beginning with the specified prefix. Mutiple filters may be attached to a
1007         * single 'ZMQ_SUB' socket, in which case a message shall be accepted if it matches at least one filter.
1008         * 
1009         * @param topic
1010         */
1011        public void subscribe(byte[] topic) {
1012            setBytesSockopt(SUBSCRIBE, topic);
1013        }
1014
1015        /**
1016         * The 'ZMQ_UNSUBSCRIBE' option shall remove an existing message filter on a 'ZMQ_SUB' socket. The filter
1017         * specified must match an existing filter previously established with the 'ZMQ_SUBSCRIBE' option. If the socket
1018         * has several instances of the same filter attached the 'ZMQ_UNSUBSCRIBE' option shall remove only one
1019         * instance, leaving the rest in place and functional.
1020         * 
1021         * @param topic
1022         */
1023        public void unsubscribe(byte[] topic) {
1024            setBytesSockopt(UNSUBSCRIBE, topic);
1025        }
1026
1027        /**
1028         * The 'ZMQ_RATE' option shall set the maximum send or receive data rate for multicast transports such as in the
1029         * man page of zmq_pgm[7] using the specified 'socket'.
1030         * 
1031         * @param rate
1032         */
1033        public void setRate(long rate) {
1034            setLongSockopt(RATE, rate);
1035        }
1036
1037        /**
1038         * The 'ZMQ_RECOVERY_IVL' option shall set the recovery interval for multicast transports using the specified
1039         * 'socket'. The recovery interval determines the maximum time in seconds (before version 3.0.0) or milliseconds
1040         * (version 3.0.0 and after) that a receiver can be absent from a multicast group before unrecoverable data loss
1041         * will occur.
1042         * 
1043         * CAUTION: Exercise care when setting large recovery intervals as the data needed for recovery will be held in
1044         * memory. For example, a 1 minute recovery interval at a data rate of 1Gbps requires a 7GB in-memory buffer.
1045         * {Purpose of this Method}
1046         * 
1047         * @param recovery_ivl
1048         */
1049        public void setRecoveryInterval(long recovery_ivl) {
1050            setLongSockopt(RECOVERY_IVL, recovery_ivl);
1051        }
1052
1053        /**
1054         * The 'ZMQ_MCAST_LOOP' option shall control whether data sent via multicast transports using the specified
1055         * 'socket' can also be received by the sending host via loopback. A value of zero disables the loopback
1056         * functionality, while the default value of 1 enables the loopback functionality. Leaving multicast loopback
1057         * enabled when it is not required can have a negative impact on performance. Where possible, disable
1058         * 'ZMQ_MCAST_LOOP' in production environments.
1059         * 
1060         * @param mcast_loop
1061         */
1062        public void setMulticastLoop(boolean mcast_loop) {
1063            if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
1064                return;
1065
1066            setLongSockopt(MCAST_LOOP, mcast_loop ? 1 : 0);
1067        }
1068
1069        /**
1070         * The 'ZMQ_SNDBUF' option shall set the underlying kernel transmit buffer size for the 'socket' to the
1071         * specified size in bytes. A value of zero means leave the OS default unchanged. For details please refer to
1072         * your operating system documentation for the 'SO_SNDBUF' socket option.
1073         * 
1074         * @param sndbuf
1075         */
1076        public void setSendBufferSize(long sndbuf) {
1077            setLongSockopt(SNDBUF, sndbuf);
1078        }
1079
1080        /**
1081         * The 'ZMQ_RCVBUF' option shall set the underlying kernel receive buffer size for the 'socket' to the specified
1082         * size in bytes. A value of zero means leave the OS default unchanged. For details refer to your operating
1083         * system documentation for the 'SO_RCVBUF' socket option.
1084         * 
1085         * @param rcvbuf
1086         */
1087        public void setReceiveBufferSize(long rcvbuf) {
1088            setLongSockopt(RCVBUF, rcvbuf);
1089        }
1090
1091        /**
1092         * The 'ZMQ_IPV4ONLY' option shall set the underlying native socket type. An IPv6 socket lets applications
1093         * connect to and accept connections from both IPv4 and IPv6 hosts.
1094         * 
1095         * @param v4only A value of true will use IPv4 sockets, while the value of false will use IPv6 sockets
1096         */
1097        public void setIPv4Only(boolean v4only) {
1098            setLongSockopt(IPV4ONLY, v4only ? 1L : 0L);
1099        }
1100
1101        /**
1102         * Sets the ROUTER socket behavior when an unroutable message is encountered.
1103         * 
1104         * @param mandatory A value of false is the default and discards the message silently when it cannot be routed.
1105         *            A value of true returns an EHOSTUNREACH error code if the message cannot be routed.
1106         */
1107        public void setRouterMandatory(boolean mandatory) {
1108            setLongSockopt(ROUTER_MANDATORY, mandatory ? 1L : 0L);
1109        }
1110
1111        /**
1112         * Sets the XPUB socket behavior on new subscriptions and unsubscriptions.
1113         *
1114         * @param verbose A value of false is the default and passes only new subscription messages to upstream.
1115         *            A value of true passes all subscription messages upstream.
1116         * @since 3.2.2
1117         */
1118        public void setXpubVerbose(boolean verbose) {
1119            if (ZMQ.version_full() < ZMQ.make_version(3, 2, 2))
1120                return;
1121              
1122            setLongSockopt(XPUB_VERBOSE, verbose ? 1L : 0L);
1123        }
1124
1125        /**
1126         * Bind to network interface. Start listening for new connections.
1127         * 
1128         * @param addr the endpoint to bind to.
1129         */
1130        public native void bind(String addr);
1131
1132        /**
1133         * Bind to network interface to a random port. Start listening for new connections.
1134         * 
1135         * @param addr the endpoint to bind to.
1136         */
1137        public int bindToRandomPort(String addr) {
1138            return bindToRandomPort(addr, 2000, 20000, 100);
1139        }
1140
1141        /**
1142         * Bind to network interface to a random port. Start listening for new connections.
1143         * 
1144         * @param addr the endpoint to bind to.
1145         * @param min_port The minimum port in the range of ports to try.
1146         */
1147        public int bindToRandomPort(String addr, int min_port) {
1148            return bindToRandomPort(addr, min_port, 20000, 100);
1149        }
1150
1151        /**
1152         * Bind to network interface to a random port. Start listening for new connections.
1153         * 
1154         * @param addr the endpoint to bind to.
1155         * @param min_port The minimum port in the range of ports to try.
1156         * @param max_port The maximum port in the range of ports to try.
1157         */
1158        public int bindToRandomPort(String addr, int min_port, int max_port) {
1159            return bindToRandomPort(addr, min_port, max_port, 100);
1160        }
1161
1162        /**
1163         * Bind to network interface to a random port. Start listening for new connections.
1164         * 
1165         * @param addr the endpoint to bind to.
1166         * @param min_port The minimum port in the range of ports to try.
1167         * @param max_port The maximum port in the range of ports to try.
1168         * @param max_tries The number of attempt to bind.
1169         */
1170        public int bindToRandomPort(String addr, int min_port, int max_port, int max_tries) {
1171            int port;
1172            Random rand = new Random();
1173            for (int i = 0; i < max_tries; i++) {
1174                port = rand.nextInt(max_port - min_port + 1) + min_port;
1175                try {
1176                    bind(String.format("%s:%s", addr, port));
1177                    return port;
1178                } catch (ZMQException e) {
1179                    if (e.getErrorCode() != ZMQ.EADDRINUSE()) {
1180                        throw e;
1181                    }
1182                    continue;
1183                }
1184            }
1185            throw new ZMQException("Could not bind socket to random port.", (int) ZMQ.EADDRINUSE());
1186        }
1187
1188        /**
1189         * Unbind from network interface. Stop listening for connections.
1190         * 
1191         * @param addr the endpoint to unbind from.
1192         */
1193        public native void unbind(String addr);
1194
1195        /**
1196         * Connect to remote application.
1197         * 
1198         * @param addr the endpoint to connect to.
1199         */
1200        public native void connect(String addr);
1201
1202        /**
1203         * Disconnect from a remote application.
1204         * 
1205         * @param addr the endpoint to disconnect from.
1206         */
1207        public native void disconnect(String addr);
1208
1209        /**
1210         * Send a message.
1211         * 
1212         * @param msg the message to send, as an array of bytes.
1213         * @param offset the offset of the message to send.
1214         * @param flags the flags to apply to the send operation.
1215         * @return true if send was successful, false otherwise.
1216         */
1217        public boolean send(byte[] msg, int offset, int flags) {
1218            return send(msg, offset, msg.length, flags);
1219        }
1220
1221        /**
1222         * 
1223         * @param msg
1224         * @param offset
1225         * @param len
1226         * @param flags
1227         * @return
1228         */
1229        public native boolean send(byte[] msg, int offset, int len, int flags);
1230
1231        /**
1232         * Perform a zero copy send. The buffer must be allocated using ByteBuffer.allocateDirect
1233         * 
1234         * @param buffer
1235         * @param len
1236         * @param flags
1237         * @return
1238         */
1239        public native boolean sendZeroCopy(ByteBuffer buffer, int len, int flags);
1240
1241        /**
1242         * Send a message.
1243         * 
1244         * @param msg the message to send, as an array of bytes.
1245         * @param flags the flags to apply to the send operation.
1246         * @return true if send was successful, false otherwise.
1247         */
1248        public boolean send(byte[] msg, int flags) {
1249            return send(msg, 0, msg.length, flags);
1250        }
1251
1252        /**
1253         * Send a String.
1254         * 
1255         * @param msg the message to send, as a String.
1256         * @return true if send was successful, false otherwise.
1257         */
1258
1259        public boolean send(String msg) {
1260            byte[] b = msg.getBytes();
1261            return send(b, 0, b.length, 0);
1262        }
1263
1264        /**
1265         * Send a String.
1266         * 
1267         * @param msg the message to send, as a String.
1268         * @return true if send was successful, false otherwise.
1269         */
1270
1271        public boolean sendMore(String msg) {
1272            byte[] b = msg.getBytes();
1273            return send(b, 0, b.length, SNDMORE);
1274        }
1275
1276        /**
1277         * Send a String.
1278         * 
1279         * @param msg the message to send, as a String.
1280         * @param flags the flags to apply to the send operation.
1281         * @return true if send was successful, false otherwise.
1282         */
1283
1284        public boolean send(String msg, int flags) {
1285            byte[] b = msg.getBytes();
1286            return send(b, 0, b.length, flags);
1287        }
1288
1289        /**
1290         * Send a message
1291         *
1292         * @param bb ByteBuffer payload
1293         * @param flags the flags to apply to the send operation
1294         * @return the number of bytes sent
1295         */
1296        public native int sendByteBuffer(ByteBuffer bb, int flags);
1297
1298        /**
1299         * Receive a message.
1300         * 
1301         * @param flags the flags to apply to the receive operation.
1302         * @return the message received, as an array of bytes; null on error.
1303         */
1304        public native byte[] recv(int flags);
1305
1306        /**
1307         * Receive a message in to a specified buffer.
1308         * 
1309         * @param buffer byte[] to copy zmq message payload in to.
1310         * @param offset offset in buffer to write data
1311         * @param len max bytes to write to buffer. If len is smaller than the incoming message size, the message will
1312         *            be truncated.
1313         * @param flags the flags to apply to the receive operation.
1314         * @return the number of bytes read, -1 on error
1315         */
1316        public native int recv(byte[] buffer, int offset, int len, int flags);
1317
1318        /**
1319         * Zero copy recv
1320         * 
1321         * @param buffer
1322         * @param len
1323         * @param flags
1324         * @return bytes read, -1 on error
1325         */
1326        public native int recvZeroCopy(ByteBuffer buffer, int len, int flags);
1327
1328        /**
1329         * Receive a message.
1330         * 
1331         * @return the message received, as an array of bytes; null on error.
1332         */
1333        public final byte[] recv() {
1334            return recv(0);
1335        }
1336
1337        /**
1338         * Receive a message as a String.
1339         * 
1340         * @return the message received, as a String; null on error.
1341         */
1342        public String recvStr() {
1343            return recvStr(0);
1344        }
1345
1346        /**
1347         * Receive a message as a String.
1348         * 
1349         * @param flags the flags to apply to the receive operation.
1350         * @return the message received, as a String; null on error.
1351         */
1352
1353        public String recvStr(int flags) {
1354            byte[] data = recv(flags);
1355
1356            if (data == null)
1357                return null;
1358
1359            return new String(data);
1360        }
1361        /**
1362         * Receive a message
1363         * 
1364         * @param buffer
1365         * @param flags
1366         * @return bytes read, -1 on error
1367         */
1368        public native int recvByteBuffer(ByteBuffer buffer, int flags);
1369
1370        /**
1371         * Class constructor.
1372         * 
1373         * @param context a 0MQ context previously created.
1374         * @param type the socket type.
1375         */
1376        protected Socket(Context context, int type) {
1377            // We keep a local handle to context so that
1378            // garbage collection won't be too greedy on it.
1379            this.context = context;
1380            construct(context, type);
1381        }
1382
1383        /** Initialize the JNI interface */
1384        protected native void construct(Context ctx, int type);
1385
1386        /** Free all resources used by JNI interface. */
1387        protected native void destroy();
1388
1389        /**
1390         * Get the socket option value, as a long.
1391         * 
1392         * @param option ID of the option to set.
1393         * @return The socket option value (as a long).
1394         */
1395        protected native long getLongSockopt(int option);
1396
1397        /**
1398         * Get the socket option value, as a byte array.
1399         * 
1400         * @param option ID of the option to set.
1401         * @return The socket option value (as a byte array).
1402         */
1403        protected native byte[] getBytesSockopt(int option);
1404
1405        /**
1406         * Set the socket option value, given as a long.
1407         * 
1408         * @param option ID of the option to set.
1409         * @param optval value (as a long) to set the option to.
1410         */
1411        protected native void setLongSockopt(int option, long optval);
1412
1413        /**
1414         * Set the socket option value, given as a byte array.
1415         * 
1416         * @param option ID of the option to set.
1417         * @param optval value (as a byte array) to set the option to.
1418         */
1419        protected native void setBytesSockopt(int option, byte[] optval);
1420
1421        /**
1422         * Get the underlying socket handle. This is private because it is only accessed from JNI, where Java access
1423         * controls are ignored.
1424         * 
1425         * @return the internal 0MQ socket handle.
1426         */
1427        private long getSocketHandle() {
1428            return this.socketHandle;
1429        }
1430
1431        /** Opaque data used by JNI driver. */
1432        private long socketHandle;
1433        private Context context = null;
1434        // private Constants use the appropriate setter instead.
1435        private static final int HWM = 1;
1436        // public static final int LWM = 2; // No longer supported
1437        private static final int SWAP = 3;
1438        private static final int AFFINITY = 4;
1439        private static final int IDENTITY = 5;
1440        private static final int SUBSCRIBE = 6;
1441        private static final int UNSUBSCRIBE = 7;
1442        private static final int RATE = 8;
1443        private static final int RECOVERY_IVL = 9;
1444        private static final int MCAST_LOOP = 10;
1445        private static final int SNDBUF = 11;
1446        private static final int RCVBUF = 12;
1447        private static final int RCVMORE = 13;
1448        private static final int FD = 14;
1449        private static final int EVENTS = 15;
1450        private static final int TYPE = 16;
1451        private static final int LINGER = 17;
1452        private static final int RECONNECT_IVL = 18;
1453        private static final int BACKLOG = 19;
1454        private static final int RECONNECT_IVL_MAX = 21;
1455        private static final int MAXMSGSIZE = 22;
1456        private static final int SNDHWM = 23;
1457        private static final int RCVHWM = 24;
1458        private static final int MULTICAST_HOPS = 25;
1459        private static final int RCVTIMEO = 27;
1460        private static final int SNDTIMEO = 28;
1461        private static final int IPV4ONLY = 31;
1462        private static final int ROUTER_MANDATORY = 33;
1463        private static final int KEEPALIVE = 34;
1464        private static final int KEEPALIVECNT = 35;
1465        private static final int KEEPALIVEIDLE = 36;
1466        private static final int KEEPALIVEINTVL = 37;
1467        private static final int XPUB_VERBOSE = 40;
1468
1469    }
1470
1471    public static class PollItem {
1472        private Socket socket;
1473        private SelectableChannel channel;
1474        private int events;
1475        private int revents;
1476
1477        public PollItem(Socket socket, int events) {
1478            th

Large files files are truncated, but you can click here to view the full file