LINUX.ORG.RU

Помогите разобраться с потоками


0

0

Пардон,вот код:

#include<sys/socket.h>
#include<sys/types.h>
#include<resolv.h>
#include<stdio.h>
#include<errno.h>
#include<glib.h>
#include<pthread.h>
#include<signal.h>

#define PROCNUM 30

GList* ips; // список ip-шников

void generate_ips()
{
int i;
for(i=1;i<255;i++)
ips=g_list_append(ips,g_strdup_printf("192.168.22.%d",i));
}

void* try_ip(void* ip)
{
int sock;
struct sockaddr_in server;
memset(&server,sizeof(server),0);

server.sin_family=AF_INET;
server.sin_port=htons(139);
server.sin_port=htons(139);
inet_aton(ip,&server.sin_addr);
sock=socket(PF_INET,SOCK_STREAM,0);

if(sock<0){
printf("error %d while creating socket!\n",errno);
exit(1);
}

if(connect(sock,&server,sizeof(server))==0){
printf("==>%s\n",ip);
close(sock);
}
raise(SIGCHLD);
return NULL;
}

void on_child_exited(int sig)
{
if(ips)
{
pthread_t child; if((pthread_create(&child,NULL,&try_ip,(void*)(ips->data)))!=0){
printf("error creating thread!\n");
}
ips=ips->next;
}
}

int main(int argc,char* argv[])
{
int ips_in_scan=0;

struct sigaction act;
memset(&act,sizeof(act),0);

act.sa_handler=on_child_exited;
act.sa_flags=SA_NOMASK | SA_RESTART; //не уверен с флагами
sigaction(SIGCHLD,&act,0);

generate_ips();
for(;ips,ips_in_scan<PROCNUM;ips=ips->next,ips_in_scan++)
{
pthread_t child;
if((pthread_create(&child,NULL,&try_ip,(void*)(ips->data)))!=0)
{
printf("error creating thread!\n");
}
}
sleep(100);
return 0;
}

anonymous

сильно поздно вчера дело было :) вопросы в первом треде: вот: Попал мне в руки как-то журнал хакер(мерзкий конечно,но бывает и там полезная инфа =) ) и там описывалась идея создания многопоточного сканера и я решил реализовать это на C в качестве упражнения по многозадачности и сети(это первые опыты,так что сильно не бейте.). Пока что получилось вот что: Идеология следующая: сначала генерю список ip,потом начинаю его читать и создаю максимально возможное число потоков.Далее я хочу чтобы как только потомок отработает,приходил сигнал родителю и он стартовал новый поток,пока есть что сканить.Результаты потомки отдают в stdin. Наткнулся на следующие проблемы: 1) После того как я создал первые n потоков,родителю больше нечего делать и он выходит.Во всех примерах,какие у меня были там бы вызывался waitpid(),но я не знаю pid`a того потомка,которого мне надо ждать,так как он может даже ещё не начат... 2) Как сделать timeout на процедуру connect() ? Чтобы если скажем через 5 секунд если потомок не вышел,убить его нафиг и продолжить со следующим адресом.. 3) В обработчике сигнала возможно нужна блокировка доступа к списку? 4) Нужны либо какие действия по очистке после завершения потомка? я что-то так и не догнал... 5) И что происходит с теми потомками,которые не завершились,а родитель вышел без waitpid и т.п. ? zombie или как ? я что-то пока не заметил никакого эффекта в ps после запуска существующей версии.. Помогите пжалста :) ! а то я что-то совсем запутался.Если есть какие-нибудь хорошие ссылки по теме - кидайте.И ещё - может я с самого начала выбрал неправильную идеологию?

anonymous
()

сильно поздно вчера дело было :) вопросы в первом треде: вот:

Попал мне в руки как-то журнал хакер(мерзкий конечно,но бывает и там полезная инфа =) ) и там описывалась идея создания многопоточного сканера и я решил реализовать это на C в качестве упражнения по многозадачности и сети(это первые опыты,так что сильно не бейте.).

Пока что получилось вот что:
Идеология следующая: сначала генерю список ip,потом начинаю его читать и создаю максимально возможное число потоков.Далее я хочу чтобы как только потомок отработает,приходил сигнал родителю и он стартовал новый поток,пока есть что сканить.Результаты потомки отдают в stdin.

Наткнулся на следующие проблемы:

1) После того как я создал первые n потоков,родителю больше нечего делать и он выходит.Во всех примерах,какие у меня были там бы вызывался waitpid(),но я не знаю pid`a того потомка,которого мне надо ждать,так как он может даже ещё не начат...

2) Как сделать timeout на процедуру connect() ? Чтобы если скажем через 5 секунд если потомок не вышел,убить его нафиг и продолжить со следующим адресом..

3) В обработчике сигнала возможно нужна блокировка доступа к списку?

4) Нужны либо какие действия по очистке после завершения потомка? я что-то так и не догнал...

5) И что происходит с теми потомками,которые не завершились,а родитель вышел без waitpid и т.п. ? zombie или как ? я что-то пока не заметил никакого эффекта в ps после запуска существующей версии..

Помогите пжалста :) ! а то я что-то совсем запутался.Если есть какие-нибудь хорошие ссылки по теме - кидайте.И ещё - может я с самого начала выбрал неправильную идеологию?

anonymous
()

Вощето сама схема сканера не очень хорошая
Я бы рекомендовал следующую схему, которая как правило дает более высокую производительность сканера:
cоздаешь массив структур типа
struct descriptor {
int sd; //дескриптор сокета
struct in_addr addr; //текущий адрес
time_t time //время прошедшее после последней операции (для таймаута)
}mass[MAX_CONNECTION_NUMBER];
затем в цикле заполняешь эти сруктуры адресами и создаешь сокеты в неблокирующем режиме, обнуляешь время.
И дальше, если в кратце, гоняешь по этому массиву в цикле с задержкой несколько милисекунд.
Подобная схема позволяет держать по несколько тысяч сканируемых адресов одновременно (попробуй создать тысячю трэдов для аналогии ;-).

Знаю что написал сумбурно........

Я когда-то написал неплохой сканер проксей, могу поделиться частью исходников.





Dead ★★★★
()

Сканер так писать неинтересно. По хорошему надо сделать SOCK_RAW/SOCK_PACKET и кидать кучу SYN пакетов и ждать ответа, иначе это будет не слишком быстро. Во-вторых, с нитями вообще труба. Ты или используй уродский интерфейс POSIX threads и делай pthread_join или используй родной (clone/rfork/sproc/etc) и тогда уже можно делать wait или ловить SIGCHLD.

Murr ★★
()

А проще всего - возьми nmap и посмотри как сделано там.

Murr ★★
()

> 1) После того как я создал первые n потоков,родителю больше нечего делать и он выходит

Для ожидания завершения потоков можно использовать pthread_join.

> 2) Как сделать timeout на процедуру connect() ? Чтобы если скажем через 5 секунд если потомок не вышел,убить его нафиг и продолжить со следующим адресом..

Можно его не убивать. Просто написать поток так, чтобы он сам завершался по истечению 5 сек неудачных коннектов.

> И ещё - может я с самого начала выбрал неправильную идеологию?

Наверное да.

smh ★★★
()

ok,всем спасибо за комментарии,буду осмысливать.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.