• 热门专题

perl网络编程小记()

作者:  发布日期:2016-04-15 21:56:37
Tag标签:小记  网络编程  
  • 当perl脚本开始执行时,默认地打开3个文件句柄:STDOUT,STDIN,STDERR
    
    STDOUT(standard outpu)是默认的输出文件句柄.发送给这个文件句柄的
    数据在用户指定的输出设备上显示,通常是脚本运行的命令窗口。
    
    STDIN(standard input)是默认输入的文件句柄,从这句柄读取的数据取自
    用户选择输入设备,通常是键盘.
    
    STDERR(即,standard error)用于错误消息,诊断,调式和其他类似的偶发输出。
    
    $line = <>;  #一次读一行
    @line = <>;  #读取所有的数据
    
    
    $bytes = read(FILEHANDLE,$buffer,$lenght,[,$offset])
    $bytes = sysread(FILEHANDLE,$buffer,$length,[,$offset])
    
    
    read()函数和sysread()函数从指定文件句柄中读取任意的数据。
    读取的长度可以达$length字节,所读的数据被置于$buffer中。
    两个函数都返回实际读取的字节数,如果是文件尾侧则返回数字。
    
    read()和sysread()的主要区别是read()使用标准的I/O缓冲而sysread()不用。
    这就意味着read()直到读取所需的实际字节数或读取文件文件尾才返回。
    相反,sysread()函数返回部分数据,它确保至少返回1个字节,但是如果它不能
    从文件句柄立即读取所需的字节数,则它将会返回它能读取的内容。
    
    
    
    $bytes=syswrite(FILEHANDLE,$data[,$lenght [,$offset]])
    syswrite()函数是一个写文件句柄的选择,可以更多地控制写的过程。
    它的参数是一个文件句柄和一标量值(变量或字符串文字)。它将数据写文件句柄,返回成功
    写入的字节数。默认地,syswrite()尝试写$data的整个内容,从字符串首字符开始.可以通过
    提供可选的$length 和$offset来改变syswrite()的上述行为,在这种情况下,syswrite()
    将从$offset指定位置开始写$length.
    
    
    $previou=select(FILEHANDLE);
    select()函数用于改变print()的默认输出文件句柄.它将文件句柄名设置为默认值,返回前面的默认
    名. select()函数是一个具有四个参数的版本,用于多路复用.
    
    
    $! 根据上下文返回的错误
    
    eof()函数,用于显示地测试条句柄的EOF条件
    
    
    行尾
      在unix系统上,行以字符(LF,ASCII表中的八进制的
    )结尾;
      在Macintosh系统上,行以回车字符(CR,八进制的
    )结尾;
      在Windows/DOS系统上决定换行以两个字符结尾,一个是回车/换行对(CRLF,或者八进制的
    ,
    )
      多数面向行的网络服务器也使用CRLF换行符终止。
    
      perl提供了一个检查并改变行尾字符的方法.全局变量$/包含用来指行尾的当前字符或字符序列.
      默认地,该变量在UNIX系统设置为
    ,在Macintosh系统上设置
    ,在Windows AND DOS系统上
      设置为
     
    .
    
      而面向行的<>输入函数将从指定的句柄读取数据,直到它遇到包含在$/中的行尾字符,然后它返回
      附有行尾的字符序列的文件本行。chomp()函数根据$/的当前值在文件字符串的尾部查找行尾的字符
      序列并删除之。
    
      binmode()函数 关闭字符转换
      binmode(FILEHANDLE,[,$disciplie])
      binmode()函数为文件句柄打开二进制模式,并取消字符转换。该函数应该在文件句柄打开之后在对
      文件句柄做任何I/O操作之前被调用。
    
    
      open(FILEHANDLE,$mode,$path);
    
      模式    描述
      <       打开文件用于读
      >       截取文件长度为0并打开用于写
      >>      打开文件用于添,不截断
      +>      截断文件,然后打开用于读/写
      <+      打开文件用于读/写,不截断
    
    
    sysopen(FILEHANDLE,$filename,$mode[,$perms]);
    sysopen()函数打开由$filename指定的文件,使用了$mode指定的I/O模式.如果文件不存在,
    并且$mode指定该文件应该创建,则可选项$perms的值明新创建文件的许可位。
    
    常量        描述
    O_RDONLY    打开用于只读
    O_WRONLY    打开用于只写
    O_RDWR      打开用于读/写
    O_EXCL      和O_CREATE组合使用时,文件不存在时创建文件,文件存在时失败
    O_TRUNC     如果文件已存在,将其截断为长度0
    O_APPEND    以添加模式打开文件(同等于open()的'>>')
    O_NOCITY    如果文件为终端设备,打开它并且不允许它成为进程的控制终端
    O_NONBLOCK  以无阻塞模式打开文件
    O_SYSNC     以同步方式打开文件,阻塞所有的写操作直到完成数据的物理写
    
    
    
    缓冲和阻塞
      当对文件句柄调用print()和syswrite()时,实际的输出操作并不是立即发生。如果对文件写,
      系统必须等待书写头到达到磁盘驱动上的合适位置,并等待旋转磁盘将写的对应位置带到书写头下面来。
    
    缓冲区在概念上是循环的FIFO(先进先出)数据结构。当写入的数据超出缓冲内存区的尾部时,操作系统仅仅
    在缓冲区的开头写入新的数据。操作系统在综的每个I/O缓冲区中维护两个指针。写指针指向新数据进入的缓冲
    区的地方。读指针所指的位置处的数据被从缓冲区中移出,写到下一目的地。
    
    
    
    两种方法能够解决stdio缓冲问题.一种方法是为文件句柄打开'autoflush'模式。'autoflush'模式
    只用于输出操作。当激活autoflush模式时,每次调用print()时perl都会告诉stdio将文件句柄的
    缓冲区中的内容送出。
    为了打开autoflush模式,应将特殊变量$|设为true值。autoflush模式影响当前选择的文件句柄,
    因此为一特定的文件句柄选择前面所选的文件句柄(使用select()).
    
    my $previous=select(FH);
    $|=1;
    select($previous);
    
    select((select(FH),$|=1)[0])
    
    另一种避免stdio缓冲的问题的方法是使用sysread()调用和syswrite()调用。这两个调用绕过了
    stdio库直接进入操作系统I/O调用。这两个调用的一个重要的有点就是可以和其他的低层I/O调用
    (例如参数的select()调用)很好相互操作,可以和高级的技术(例如无阻塞I/O)很好的相互操作。
    
    
    
    
    传递和存储文件句柄
    
    有时你需要检查一标量看其是否包含一信有效的文件句柄.fileno()函数可以满足这个需要;
    
    $integer=fileno(FILEHANDLE);
    
    fileno()函数以字符串形式,typeglob形式或typeglob引用形式接受文件句柄。如果文件句柄有效,
    则fileno()返回文件句柄的文件描述符(file descriptor).文件描述符是个小整数,唯一标识操作
    系统的文件句柄.一般地,STDIN,STDOUT,STDERR分别对就描述符0,1,2(如果你关闭重新打开它们则可以
    以改变其描述符)。其他文件句柄具有大于3的描述符。
    
    
    
    错误检测
    
    use Errno qw(EACCES ENOENT);
    
    my $resutl = open(FH,'/etc/passwd1');
    if(!$resutl)  #oops,something went wrong
    {
     if($! == EACCES)
     {
        warn 'You do not have permission to open the file.
    ';
     }
     elsif($! == ENOENT)
     {
        warn 'File or directory not found.
    ';
     }
     else
     {
        warn 'Some other error occurred: $!
    ';
     }
    }
    
    
    IO::Handle 模块和IO::File模块
    
    #!/usr/bin/perl
    #打开一个文件,统计文件的行数
    use strict;
    use warnings;
    use IO::File;
    
    my $file = shift;
    my $counter = 0;
    my $fh = IO::File->new($file) or die 'Cant open $file:$!
    ';
    while(defined(my $file = $fh->getline()))
    {
       $counter++;
    }
    
    STDOUT->print('Counted $counter lines
    ');
    
    
    IO::File->new($filename [,$mode [,$perms]])
    new()方法是IO::File的主要构造函数.它是open()和sysopen()的统一替代物。
    例如:将打开指定文件用于添:
    $fh=IO::File->new('>darkstar,txt');
    
    $fh=IO::File->new_tmpfile();
    new_tmpfile()构造函数被调用时不需要参数,它创建一个临时文件并打开用于读和写。
    在UNIX系统上,该文件是匿名的,意味着它对文件系统不可见。当撤销IO::File对象时,这
    个文件和它的全部内容将自动删除。这个构造对存储大量的临时文件很有用。
    $resutl=$fh->close;
    
    $result=$fh->open($file [,$mode [,$perms]]);
    可以使用open()方法对指定的谁的重新打开 一个文件句柄对象.输入的参数和new()相同。方法
    的结果指示打开操作是否成功完成。
    这个方法主要用来重新打开标准的文件句柄STDOUT,STDIN,STDERR.
    STDOUT->open('>log.txt') or die 'Cant reopen STDOUT:$!';
    对print()的调用现在将写入文件log.txt
    
    $result=$fh->print(@args);
    $result=$fh->printf($fmt,@args);
    
    
    $bytes=$fh->write($data[,$length [,$offset]]);
    $bytes=$fh->syswrite($data[, $length [,$offset]]);
    
    print(),printf()和syswrite()三个方法的工作机制和它们的内置对应函数完全一样。
    例如,print()接收一系列数据项,将它们写入文件句柄的对象,并当成功写入时返回true.
    
    write() and read()相反,将字节流写入文件句柄对象并返回成功写入的字节数。
    
    
    $lines=$fh->getline;
    @linges=$fh->getlines;
    $bytes=$fh->read($buffer,$legal[,$offset])
    $bytes=$fh->sysread($buffer,$length[,$offset])
    getline()和getlines()两个方法一起代替了<>运算符。getline()从文件句柄对象读取一行
    并返回它,对村量下下文和列表上下文其行为一样。getlines()方法在列表上下文中和<>的行为
    一样,返回所有能获得的行一个列表。getline)在文件尾将返回undef;
    
    $previous=$fh->autoflush([$boolean])
    autoflush()方法获取或设置文件句柄对象的autoflush模式。无参数调用时,它打开autoflush.
    以单一布尔参数被调用时,它将autoflush设置指定状态。两种情况下,autoflush()都返回autoflush
    状态的前一个值。
    $boolean=$fh->opened;
    如果文件句柄对象是肖有效的则opened()方法返回true.它造价于:
    defined filno($fh);
    $boolean=$fh->eof;
    
    如果下次对文件句柄对象读取操作将返回EOF,则该方法返回true;
    
     $fh->flush;
     flush()方法立即'涌出'缓冲在文件句柄对象中的任何数据。如果文件句柄用于写,则将其缓冲
     的数据写向磁盘(或者管道,网络)。如果文件句柄用于读,则丢弃缓冲区中的任意数据,强制下
     一次从磁盘读取。
    
     $boolean=$fh->block([$boolean])
     blocking()方法作为文件句柄打开和关闭阻塞模式。
    
    $fh->clearerr;
    $boolean=$fh->error;
    如果你希望执行一系列I/O操作并且只在完成之后检查错误的状态,则用这两个方法会很方便。
    如果在文件句柄被创建以来或在最后一次调用clearerr()以来发生了任何错误,则error()
    将返回true.clearerr()方法清除该错误标志。
    
    
    
    -----------------------------------------------------
    进程,管道和信号
    -----------------------------------------------------
    
    
    进程
    
    perl支持两种类型的多任务。一种类型基于传统的UNIX多进程模型,允许当前进程通过fork()
    函数复制它本身。一个进程做一项任务,另一个进程做另一个项任务。
    另一种基于现代更轻便'线程'。将所有的任务保持在单一进程内容。然而,一个单一程序可以具有
    多个执行的线程在其中运行,每一线程都独立其他线程而运行。
    
    perl的fork()函数不带参数并且返回一个数值型结果码。当调用fork()时,它生成一个当前进程的
    精确拷贝.称为子进程的这个拷贝共享所有变量,文件句柄(包括标准I/O缓冲区中的数据)和基他
    数据结的所有当前值。事实上,这个复制的过程甚至具有调用fork()的内存。
    
    调用fork()之后,父进程和子进程都检查函数的返回值。在父进程中,fork()返回子进程的PID。
    在子进程中,fork()返回数值0.代码如果发现它是父进程就会开始做一件事情,如果它是子进程
    就会做另一件事情。
    
    $pid=fork();
    派生一个新进程。在父进程中返回子进程的PID,在子进程中返回0.发生错误时(例如没有足够的
    内存派生子进程),返回undef,并将$!设置为适当的错误消息。
    
    如在调用fork()之后父进程和子进程希望相互通信,它们可以通过管道来完成或者通过共享内存
    来完成。对于简单的消息,父进程和子进程可以使用kill()函数来给相互的PID发送信号。父进程
    从fork()的结果代码中获取了子进程的PID,而子进程通过调用getppid()来获取父进程的PID。
    一个进程可以通过检查$$特殊变量来获取它自己的PID.
    
    $pid = getppid();
    返回父进程的PID,每个perl脚本都具有父进程,甚至那些直接从命令运行的perl脚本也有父进程
    (它们的父进程是shell进程)
    
    $$
    $$变量保存当前进程的PID。它可读但不能改变。
    
    
    如果子进程愿意,它本身也可以调用fork()创建孙子进程。原始进程父进程也可以再次调用fork()
    创建子进程,其子进程和孙子进程也都可以。以这种方式,perl脚本可以创建一个进程的整个部落。
    这个部落的每个成员属于相同的进程组(process group)
    
    每个进程都有一个唯一的ID,通常和共享的祖先的进程ID相同。该值可以通过调用getpgrp()获得:
    $processid=getpgrp([$pid]);
    对于$pid指定的进程,getpgrp()函数返回它的进程组ID,如果没有指定PID,则返回当前进程的进程组。
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    print 'PID=$$
    ';
    
    my $child = fork();
    die 'Cant fork:$!
    ' unless defined $child;
    
    if($child > 0)
    {
       print 'Parent process: PID=$$, child=$child
    ';
    }
    else
    {
       #child process
       my $ppid=getppid();
       print 'Child process: PID=$$, Parent=$ppid
    ';
    }
    ~
    
    
    system()函数和exec()函数
    perl的另一种运行子进程方法使用system().system()将另一个程序作为子进程运行,等待它的完成,
    然后返回。如果运行成功,system()返回结果码0,反之,如果程序不能开始运行就返回-1,如果程序
    错误终止则返回程序的终止状态。
    
    $status=system('command and aguments');
    $status=system('command','and','arguments');
    system()函数将一个命令作为子进程执行并等待它终止。命令及其参数可以作为一个单一字符串指定,
    或者作为一个列表指定,该列表包含命令及其参数,但都作为独立的元素。
    
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规