?
Solved

how to poll file descriptors in java

Posted on 2011-02-19
5
Medium Priority
?
1,100 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Are You Using the Best Web Development Editor?

The worlds of web hosting and web development are constantly evolving. Every year we see design trends change, coding standards adapt and new frameworks/CMS created. With such a quick pace of change it’s easy to get lost trying to keep up.

See if your editor made the list.

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
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…
Suggested Courses
Course of the Month11 days, 18 hours left to enroll

752 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