2013-09-27 2 views
0

Я заметил, что netcat не позволяет слушать порты только отдельных портов. Я написал базовую netcat-подобную программу на C с клиентом и функциями сервера. Теперь я изучаю, как лучше всего будет слушать несколько портов.Связывание/прослушивание нескольких портов, является правильным способом?

Я бы постарался использовать как: program localhost 200 300 (где 200 начинается и 300 заканчивается портом).

Является ли pthreads лучшим способом для этого? Привязать/слушать в каждом потоке, а затем, когда соединение будет создано, присоедините их к резервному копированию?

iret1 = pthread_create(&thread1, NULL, bind_function, (void*) somename); 
pthread_join(thread1, NULL); 

Threading действительно новые земли, и я не уверен, если есть более простой способ, или как бы вы использовали iret1 (возвращаемое значение), дополнительно. Может кто-нибудь добавить к этому?

Примечания для Dolda2000:

пример использования на Epoll я наткнулся:

for (j = 1; j < argc; j++) { 
     fd = open(argv[j], O_RDONLY); 
     if (fd == -1) 
      errExit("open"); 
     printf("Opened \"%s\" on fd %d\n", argv[j], fd); 

     ev.events = EPOLLIN;   /* Only interested in input events */ 
     ev.data.fd = fd; 
     if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) 
      errExit("epoll_ctl"); 
    } 

Мой Binding код:

if (bind(sockfd, (struct sockaddr *) &server_addr, server_len) < 0) 
     error("ERROR"); 
     listen(sockfd,5); 

newsockfd = accept(sockfd, (struct sockaddr *) &client_addr, &clilen); 
+0

Если вы просто хотите слушать, видеть @ ответ Dolda2000 в. Есть некоторые вещи, которые будут мотивировать потоки по выбору, но просто слушать порты не является одним из них. – jedwards

+0

По умолчанию в каждой ветке по умолчанию накладные расходы ~ 8 МБ, forking обычно легче для небольших программ (<8mb), но select/poll/epoll будет еще легче – technosaurus

ответ

2

Конечно, было бы проще и менее ресурсоемким вместо этого использовать select/poll/epoll?

Я не уверен, что именно у вас возникли проблемы с, так вот пример кода с использованием poll:

int listentoall(int firstport, int lastport) 
{ 
    int i, nsk; 
    int nfd = lastport - firstport + 1; 
    struct pollfd fds[nfd]; 
    struct sockaddr_in name; 

    memset(&name, 0, sizeof(name)); 
    name.sin_family = AF_INET; 
    for(i = 0; i < nfd; i++) { 
     fds[i].fd = socket(PF_INET, SOCK_STREAM, 0); 
     name.sin_port = htons(firstport + i); 
     bind(fds[i].fd, (struct sockaddr *)&name, sizeof(name)); 
     listen(fds[i].fd, 5); 
     fds[i].events = POLLIN; 
    } 

    while(1) { 
     poll(fds, nfd, -1); 
     for(i = 0; i < nfd; i++) { 
      if(fds[i].revents & POLLIN) { 
       nsk = accept(fds[i].fd, NULL, NULL); 
       for(i = 0; i <nfd; i++) 
        close(fds[i].fd); 
       return(nsk); 
      } 
     } 
    } 
} 

Обратите внимание, что я только что написал этот код прямо сейчас без компиляции, так что вполне может быть опечатки и многое другое, и, очевидно, проверка ошибок не выполняется, но, возможно, этого достаточно, чтобы объяснить общую структуру?

+0

Мне жаль, как бы вы перебирали через привязки портов в диапазоне и регистрировали их для epoll? Также я прав, думая, что выбора недостаточно для полного диапазона портов 1- 65 тыс.? Как только соединение будет получено на любом из портов, я хочу, чтобы все они были неблокированы и перестали слушать отдельно от того, который подключен. – OBV

+0

Что вам интересно об итерации всех сокетов? Это API, который вы не понимаете, или что-то еще? Вы были бы правы, думая, что 'select' не заходит так далеко, однако; но и «опрос», и «epoll» будут работать. – Dolda2000

+0

Благодарим вас за ответ. Я обновил свой пост с использованием примера api и под ним, как я привязываю/слушаю/принимаю для одного порта. То, что я подразумеваю под итерацией, это то, что я мог бы сделать цикл for, чтобы связать/прослушать диапазон портов, но тогда я не уверен в взаимодействии epoll с accept(). – OBV

Смежные вопросы