***条件和时间问题,程序暂时还没进行测试.
unix并发技术的学习及在扫描器上的应用一
我一直学着写扫描器.我的一个方向是:多进程–多线程–线程安全(MT-safe).都想在扫描器上实现.现在学习多进程部分.
第一部分–基本知识
一.进程概念:
进程定义了一计算的基本单位,是一个执行某一特定程序的实体.它拥有自己的地址空间,执行堆栈,文件描述符表等。
二.创建进程:
1.fork()函数原型
#include
#include
pid_t fork(viod);
2.返回值
子进程为0,父进程为子进程id,出错为-1.
3.fork()函数用法
两个用法:
一个父进程通过复制自己,使父子进程同时执行不同的代码段.这对网络服务进程是常见的:父进程等待客户的服务请求.当这种请求到达时,父进程调用fork()
函数,使子进程处理此请求.父进程则继续等待下一个客户服务请求.
每个进程要执行不同的程序,这会shell是常见的,在这种情况下,子进程在从fork()函数返回后立即调用exec()函数执行其他程序.
用法:
#include
#include
main()
{
pid_t pid;if((pid=fork())>0)
{
/*parent process*/
}
else if(pid==0)
{
/*child process*/
exit(0);
}
else
{
printf("fork error/n");
eixt(0);
}
}
4.进程终止
两种可能
–父进程先于子进程终止.
所有子进程的父进程改变为init进程称为进程由init进程领养.
–子进程先于父进程终止.
父进程调用wait()函数或者waitpid()函数可以得到子进程的进程id,进程的终止状态,以及进程使用的cpu时间总量.
进程正常或者异常终止,系统内核就向其父进程发送SIGCHLD信号.
5.进程终止调用的函数
1.wait()函数
等待子进程返回并修改状态
#include
#include
pid_t wait(int *stat_loc);
允许调用进程取得子进程的状态信息。调用进程将会挂起直到其一个子进程终止.
返回值为该子进程进程号,否则返回-1,同时stat_loc返回子进程的返回值.
用法:
#include
#include
main()
{
pid_t pid;
if ((pid=fork())>0)
{
/*parent process*/
int child_status;
wait(&child_status);
}
else if(pid==0)
{
/*child process*/
exit(0);
}
else
{
printf("fork error/n");
exit(0);
}
}
2.waitpid()函数
等待指定进程的子进程返回,并修改状态.
#include
#include
pid_t waitpid(pid_t pid,int *stat_loc,int options);
当pid等于-1,options等于0时,该函数等同于wait()函数。
否则该函数的行为由参数pid和options决定。
pid指定了父进程要求知道那些子进程的状态,其中:
=-1 要求知道任何一个子进程的返回状态;
>0 要求知道进程号为pid的子进程的状态;
options参数为以位方式表示的标志,它是各个标志以“或”运算组成的位图,每个标志以字节中某个位置1表示:
WUNTRACED 报告任何未知但已停止运行的指定进程的子进程状态,该进程的状态自停止运行时起就没有被报告过.
WCONTINUED 报告任何继续运行的指定进程的子进程状态,该子进程的状态自继续运行起就没有被报告过
WNONANG 若调用本函数时,指定进程的子进程状态,目前并不是立即有效的(即可被立即读取的),调用进程不被挂起执行。
WNOWAIT 保持那些将其状态设置在stat_loc()函数的进程处于可等待状态,该进程将直到下次被要求其返回状态值.
返回值为该子进程号,否则为-1,同时stat_loc()函数返回子进程的返回值
用法:
#include
#include
main()
{
pid_t pid;
if ((pid=fork())>0)
{
/*parent process*/
int child_status;
pid_t child_status;
waitpid(child_pid,&child_status,0);
}
else if (pid==0)
{
/*child process*/
exit(0);
}
else
{
printf("fork error");
exit(0);
}
}
exit()函数
终止进程,并返回状态。
#include
viod eixt(int status);
函数终止调用进程,exit()函数会关闭所有进程打开的描述符,向其父进程发送 SIGCHLD信号,并返回状态,父进程可通过调用wait()或者waitpid()函数获得其状态
第二部分–多进程80banner扫描器的具体实现
一.思路:
1.多ip处理模块
利用strtok()函数来分离ip
strtok(ip,”.”);
for来循环ip
2.usage提示模块
int usage(char *pro)
{
printf("fork 80 banner scanner");
printf("usage:%s [startip] [stopip]/n",pro);
}
3.扫描模块
viod scanip(char sip[20])
4.多进程及处理模块
fork()
二.实现
/********************************************************************
**fork() 80 banner scanner ver1.0
*
*to complie:
*user$gcc -o 80scaner 80scanner.c
*
*to use:
*user$./80scanner start_ip stop_ip (the best input c class ip otherwise *waste too many system resource )
*
*coded by nightcat
*june 2003*********************************************************************/
/*所要的文件*/
#include
#include
#include
#include
#include
#include
#include
#include
#include /*声明函数*/
int usage(char *pro);
void scanip(char *sip);int main(int argc,char *argv[])
{
/*声明变量*/
int child_status;
pid_t child_id;
pid_t pid;
char *pro;
int count;char *start_ip,*stop_ip;
char *chge;
char scan_ip[20];int ip1,ip2,ip3,ip4;
int end1,end2,end3,end4;/*输入参数判断*/
if(argc
三.总结:
调试的问题:
1.sprintf(scan_ip,”%d.%d.%d.%d”,ip1,ip2,ip3,count);这条语句提示溢出,主要是scan_ip分配的内存空间不够,由原来char *scan_ip 改为char scan_ip[20]
问题解决
2.send(s,”HEAD / HTTP/1.0/n/n”,17,0);这条语句发送后没有得到回归的信息,只要是HTTP/1.0少了两个回车/n/n,加上就可以啦!
其中新学的东西有:
1.ip的处理方法
2.多进程的使用方法
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net