Solved

how to poll file descriptors in java

Posted on 2011-02-19
5
1,030 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 500 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
The viewer will learn how to implement Singleton Design Pattern in Java.

707 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now