首页 > 其他分享 >unix并发技术的学习及在扫描器上的应用一

unix并发技术的学习及在扫描器上的应用一

时间:2023-04-09 22:07:50浏览次数:32  
标签:fork 扫描器 函数 int pid 并发 unix 进程 include


***条件和时间问题,程序暂时还没进行测试.

               unix并发技术的学习及在扫描器上的应用一

我一直学着写扫描器.我的一个方向是:多进程--多线程--线程安全(MT-safe).都想在扫描器上实现.现在学习多进程部分.

第一部分--基本知识 
一.进程概念:

进程定义了一计算的基本单位,是一个执行某一特定程序的实体.它拥有自己的地址空间,执行堆栈,文件描述符表等。

二.创建进程:

1.fork()函数原型
#include <sys/types.h>
#include <unistd.h>
pid_t fork(viod);

2.返回值
子进程为0,父进程为子进程id,出错为-1.

3.fork()函数用法

两个用法:
  一个父进程通过复制自己,使父子进程同时执行不同的代码段.这对网络服务进程是常见的:父进程等待客户的服务请求.当这种请求到达时,父进程调用fork()
函数,使子进程处理此请求.父进程则继续等待下一个客户服务请求.
  每个进程要执行不同的程序,这会shell是常见的,在这种情况下,子进程在从fork()函数返回后立即调用exec()函数执行其他程序.

用法:

#include <sys/types.h>
#include <unistd.h>
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 <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *stat_loc);
允许调用进程取得子进程的状态信息。调用进程将会挂起直到其一个子进程终止.
返回值为该子进程进程号,否则返回-1,同时stat_loc返回子进程的返回值.
用法:

#include <sys/type.h>
#include <sys/wait.h>
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 <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *stat_loc,int options);
当pid等于-1,options等于0时,该函数等同于wait()函数。

否则该函数的行为由参数pid和options决定。
pid指定了父进程要求知道那些子进程的状态,其中:
=-1 要求知道任何一个子进程的返回状态;
>0 要求知道进程号为pid的子进程的状态;
<-1 要求知道进程组号为pid的绝对值的子进程的状态.

options参数为以位方式表示的标志,它是各个标志以“或”运算组成的位图,每个标志以字节中某个位置1表示:

WUNTRACED 报告任何未知但已停止运行的指定进程的子进程状态,该进程的状态自停止运行时起就没有被报告过.

WCONTINUED 报告任何继续运行的指定进程的子进程状态,该子进程的状态自继续运行起就没有被报告过

WNONANG 若调用本函数时,指定进程的子进程状态,目前并不是立即有效的(即可被立即读取的),调用进程不被挂起执行。

WNOWAIT 保持那些将其状态设置在stat_loc()函数的进程处于可等待状态,该进程将直到下次被要求其返回状态值.

返回值为该子进程号,否则为-1,同时stat_loc()函数返回子进程的返回值
用法:

#include <sys/types.h>
#include <sys/wait.h>
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<stdlib.h>
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 <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>/*声明函数*/
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<3){
usage(argv[0]);
exit(1);
}/*处理ip*/
start_ip=argv[1];
chge=strtok(start_ip,".");
ip1=atoi(chge);
chge=strtok(NULL,".");
ip2=atoi(chge);
chge=strtok(NULL,".");
ip3=atoi(chge);
chge=strtok(NULL,".");
ip4=atoi(chge);stop_ip=argv[2];
chge=strtok(stop_ip,".");
end1=atoi(chge);
chge=strtok(NULL,".");
end2=atoi(chge);
chge=strtok(NULL,".");
end3=atoi(chge);
chge=strtok(NULL,".");
end4=atoi(chge);/*循环扫描*/
for(count=ip4;count<=end4;count++){
sprintf(scan_ip,"%d.%d.%d.%d",ip1,ip2,ip3,count);
/*产生进程*/
if((pid=fork())==0){
 scanip(scan_ip);
 exit(0);
}
}
}/*用法函数*/
int  usage(char *pro){
printf("fork() 80 banner scanner/n");
printf("input c class ip");
printf("usage:%s [start_ip][stop_ip]/n",pro);
}/*扫描函数*/
void scanip(char sip[20]){
  struct sockaddr_in addr;
  int s;
  char buffer[1024];
  if((s=socket(AF_INET,SOCK_STREAM,0))<0){
   perror("socket error/n");
   exit(1);
   }
  addr.sin_family=AF_INET;
  addr.sin_addr.s_addr=inet_addr(sip);
  addr.sin_port=htons(80);
  if(connect(s,(struct sockaddr *)&addr,sizeof(addr))<0){
   perror("connect error");
   exit(1);
   }
  send(s,"HEAD / HTTP/1.0/n/n",17,0);
  recv(s,buffer,sizeof(buffer),0);
  printf("%s's http version:/n%s",sip,buffer);
  close(s);
  sleep(5);
  exit(0);
 }

三.总结:

调试的问题:

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.多进程的使用方法

标签:fork,扫描器,函数,int,pid,并发,unix,进程,include
From: https://blog.51cto.com/u_1790502/6179211

相关文章

  • 【Java 并发】【十】【JUC数据结构】【六】SynchronousQueue同步阻塞队列原理
    1 前言看过了LinkedBlockingQueue、ArrayBlockingQueue、DelayQueue等阻塞队列,这节我们又要看一个不一样的队列,SynchronousQueue同步阻塞队列。2 SynchronousQueue是什么SynchronousQueue的同步队列,使用的场景比较少,主要是用来做线程之间的数据同步传输的。线程之间的同步......
  • 【Java 并发】【十】【JUC数据结构】【五】DelayQueue延迟阻塞队列原理
    1 前言前两节我们看了BlockingQueue阻塞队列的两个子类,LinkedBlockingQueue、ArrayBlockingQueue,它们都是使用了ReentrantLock、Condition的来实现的,在进行插入操作、拉取数据操作之前为了并发安全都需要进行加锁;然后插入时候在容量满的时候发现没有空间了,这时候调用Condition.......
  • 【Java 并发】【十】【JUC数据结构】【三】LinkedBlockingQueue阻塞队列原理
    1 前言这节我们就来看看LinkedBlockingQueue内部实现的原理。2 LinkedBlockingQueue的使用在看原理之前我们先来用一用LinkedBlockingQueue,来体验一下:2.1  插入数据publicclassLinkedBlockingQueueTest{publicstaticvoidmain(String[]args)throwsInter......
  • 【Java 并发】【十】【JUC数据结构】【一】CopyOnWriteArrayList原理
    1 前言我们前面看过了volatile、synchronized以及AQS的底层原理,以及基于AQS之上构建的各种并发工具,ReentrantLock、CountDownLatch、Semaphore、CyclicBarrier,那么我们这节该看什么了,是不是要看运用了。在日常的业务编程中经常使用到的内存数据结构有:Map、Set、List、Queue系列......
  • 并发兼容性测试
    Web测试项目中经常进行浏览器兼容性相关的测试工作,因为兼容性测试的工作重复性相当高,所以导致手工测试效率低下测试人员积极性降低。TestNG提供了并发执行测试用例的功能,可以让测试用例以并发的形式执行,实现测试不同浏览器的兼容性测试。下面代码中分别使用Chrome、Firefox和......
  • Lunix常用命令
    ll查看当前目录下的所有文件pwd查看当前位置cd进入某个文件夹wget是Linux系统用于从Web下载文件的命令行工具,支持HTTP、HTTPS及FTP协议下载文件tar压缩加压命令tarxvf解压某个压缩包su切换管理员whereis  which查找文件或文件夹rm删除文件命令./config--p......
  • C++ 并发编程实战 第二章 线程管控
    第二章线程管控std::thread简介构造和析构函数///默认构造///创建一个线程,什么也不做thread()noexcept;///带参构造///创建一个线程,以A为参数执行F函数template<classFn,class...Args>explicitthread(Fn&&F,Args&&...A);///拷贝构造(不可用)thread......
  • 【Java 并发】【九】【AQS】【八】ReentrantReadWriteLock之ReadLock读锁原理
    1 前言上节我们看了下ReentrantReadWriteLock读写锁的写锁的申请和释放过程,这节我们就来看下读锁的。2 线程读锁记录回顾一下之前的例子,在读写并发操作的时候,读取数据的时候加读锁:publicclassReentrantReadWriteLockTest{//声明一个读写锁privatestaticR......
  • MVCC——多版本并发控制
    概念MultiVersionConcurrencyControl,用于数据库的并发访问控制MVCC在mysqlinnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,实现读写冲突不加锁,非阻塞并发读写每一次的数据修改都会将历史记录保存在Undolog里,读数据采用快照读的方式,这......
  • 【并发编程】Java7 - ForkJoin,将大任务拆分成小任务
    1.简介  Java7提供了可以将大任务拆分成小任务执行再合并结果的框架——Fork/Join。其中,将大任务拆分成足够执行的小任务并发执行的过程称为Fork,将这些小任务结果整合后形成最终的结果的过程称为Join。  Fork/Join框架的具体体现为ForkJoinTask抽象类,该类继承了Future,运行......