?
Solved

how to poll file descriptors in java

Posted on 2011-02-19
5
Medium Priority
?
1,173 Views
Last Modified: 2012-05-11
Hello,

My Java application needs to poll a number of file descriptors to determine which one is ready for input. I know there is Selector class in Java, but the problem is the file descriptors which needs to be polled come from JNI code (from libpcap's pcap_get_selectable_fd() in fact).

Is there any way to work with these descriptors via the standard or perhaps a customized Selector? I have looked at implementing SelectableChannel or extending AbstractSelectableChannel, but can't figure out how to implement it properly and what other classes needs to be extended.

Attached is a sample C code illustrating select() loop which I would like to implement in Java. As I have said, instead of implementing this loop as is in JNI, I would like to reuse existing Selector framework.

Thanks in advance for your feedback.
/**
 * This function initializes a live capture PCAP handle and possibly
 * grabs a selectable file handle.
 */
pcap_t*
pcap_alloc(const char *dev, int *fd) {
    pcap_t *handle;
    char errbuf[PCAP_ERRBUF_SIZE];

#ifdef USE_PCAP100
    handle = pcap_create(dev, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        exit(EXIT_FAILURE);
    }

    if (pcap_set_promisc(handle, 1) < 0) {
        pcap_perror(handle, "pcap_set_promisc");
        exit(EXIT_FAILURE);
    }

    if (pcap_activate(handle) < 0) {
        pcap_perror(handle, "pcap_activate");
        exit(EXIT_FAILURE);
    }
#else
    handle = pcap_open_live(dev, 64 * 1024 /* snaplen */, 1 /* promisc */, 1 /* timeout */, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        exit(EXIT_FAILURE);
    }

    /* make sure we're capturing on an Ethernet device */
    if (pcap_datalink(handle) != DLT_EN10MB) {
        fprintf(stderr, "%s is not an Ethernet\n", dev);
        exit(EXIT_FAILURE);
    }
#endif

    if (fd) {
#if USE_PCAP_SELECT
        *fd = pcap_get_selectable_fd(handle);
        if (*fd < 0) {
            fprintf(stderr, "Failed to get selectable FD for PCAP handle\n");
            exit(EXIT_FAILURE);
        }
#else
        *fd = -1;
#endif // USE_PCAP_SELECT
    }

    return handle;
}

/**
 * main() expects two parameters -- names of the network interfaces to bridge
 */
int
main(int argc, char *argv[]) {
    int f_pcap1, f_pcap2;
    pcap_t *pcap1, *pcap2;

    assert(argc == 3);
    pcap1 = pcap_alloc(argv[1], &f_pcap1);
    pcap2 = pcap_alloc(argv[2], &f_pcap2);

#if USE_PCAP_SELECT
    int fm = max(f_pcap1, f_pcap2) + 1;
#endif // USE_PCAP_SELECT

    for (;;) {
#if USE_PCAP_SELECT
        fd_set fds;

        FD_ZERO(&fds);
        FD_SET(f_pcap1, &fds);
        FD_SET(f_pcap2, &fds);

        int res = select(fm, &fds, NULL, NULL, NULL);
        if (res < 0) {
            perror("select");
            continue;
        } else if (res == 0) {
            continue;
        }

        if (FD_ISSET(f_pcap1, &fds)) {
            forward(pcap1, pcap2);
        }

        if (FD_ISSET(f_pcap2, &fds)) {
            forward(pcap2, pcap1);
        }
#else
        forward(pcap1, pcap2);
        forward(pcap2, pcap1);
#endif // USE_PCAP_SELECT
    }
}

Open in new window

0
Comment
Question by:gremwell
  • 4
5 Comments
 
LVL 47

Accepted Solution

by:
for_yan earned 2000 total points
ID: 34932369

This looks like dealing with similar issue, but it still uses JNI:
http://www.kfu.com/~nsayer/Java/jni-filedesc.html

This code illustrates the use of Selector listening to server sockets,
rathe than files; still may happen to be of some use
http://www.javafaq.nu/java-example-code-353.html

This is I guess also relevant discussion (looks lik it still cannot be  done in pure Java):
http://stackoverflow.com/questions/3893236/java-detecting-modification-to-a-file-file-polling
0
 
LVL 47

Expert Comment

by:for_yan
ID: 34932399
0
 
LVL 47

Expert Comment

by:for_yan
ID: 34932428
And, finally, maybe you want to be the first to try Java 7 which has WatchService API, which would probably, do what you want:

http://java.sun.com/developer/technicalArticles/javase/nio/#6

http://dlc.sun.com.edgesuite.net/jdk7/binaries/index.html
0
 
LVL 3

Author Comment

by:gremwell
ID: 34933323
Thanks for your feedback! The first link you have provided -- wrapping native file descriptor into Java FileDescriptor objects -- seems to be relevant to my goal. The next question would be how to produce a selectable channel out of FileDescriptor. By looking at JDK sources I have found sun.nio.ch.SourceChannelImpl class (extending Pipe.SourceChannel, extending AbstractSelectableChannel), which I will try to repurpose.
0
 
LVL 47

Expert Comment

by:for_yan
ID: 34933401
Great! I'm happy there was something useful. And just for my understanding when you say "to determine which one is ready for input" do you mean that your application needs to write big blocks of data to several files, and you do it in separate thread, so after you dispatched say first block of data to each of the files you want to know which one is done with writing and is now ready to accept next input - is it something like that?
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have seen several blogs and forum entries elsewhere state that because NTFS volumes do not support linux ownership or permissions, they cannot be used for anonymous ftp upload through the vsftpd program.   IT can be done and here's how to get i…
In this post we will learn different types of Android Layout and some basics of an Android App.
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month5 days, 12 hours left to enroll

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question