Perl accept 函数

  • 描述

    accept 接受现有GENERICSOCKET上的传入连接,该连接应该已经使用套接字创建并使用bind绑定到本地地址。用于与客户端通信的新套接字为NEWSOCKETGENERICSOCKET将保持不变。
  • 句法

    以下是此函数的简单语法-
    
    accept NEWSOCKET,GENERICSOCKET
    
  • 返回值

    该函数在失败时返回0,在成功时返回远程主机的压缩地址。
  • 示例

    以下是显示其基本用法的示例代码 (客户端)-
     
    # tcp_socket_cli.pl
    use strict;
    use Socket;
    
    my $addr = $ARGV[0] || '127.0.0.1';
    my $port = $ARGV[1] || '3000';
    my $dest = sockaddr_in($port, inet_aton($addr));
    my $buf = undef;
    
    socket(SOCK,PF_INET,SOCK_STREAM,6) or die "Can't create socket: $!";
    connect(SOCK,$dest)                or die "Can't connect: $!";
    
    my $bs = sysread(SOCK, $buf, 2048); # try to read 2048
    print "Received $bs bytes, content $buf\n"; # actually get $bs bytes
    close SOCK;
    
    服务端
    
    # tcp_socket_dt_srv.pl
    use strict;
    use Socket;
    use IO::Handle;
    use POSIX qw(WNOHANG);
    
    my $port     = $ARGV[0] || '3000';
    my $proto    = getprotobyname('tcp');
    
    $SIG{'CHLD'} = sub {
         while((my $pid = waitpid(-1, WNOHANG)) >0) {
              print "Reaped child $pid\n";
          }
    };
    
    socket(SOCK, AF_INET, SOCK_STREAM, getprotobyname('tcp'))
        or die "socket() failed: $!";
    setsockopt(SOCK,SOL_SOCKET,SO_REUSEADDR,1)
        or die "Can't set SO_REUSADDR: $!" ;
    
    my $my_addr = sockaddr_in($port,INADDR_ANY);
    bind(SOCK,$my_addr)    or die "bind() failed: $!";
    listen(SOCK,SOMAXCONN) or die "listen() failed: $!";
    
    warn "Starting server on port $port...\n";
    
    while (1) {
         next unless my $remote_addr = accept(SESSION,SOCK);
         defined(my $pid=fork) or die "Can't fork: $!\n";
    
         if($pid==0) {
              my ($port,$hisaddr) = sockaddr_in($remote_addr);
              warn "Connection from [",inet_ntoa($hisaddr),",$port]\n";
              SESSION->autoflush(1);
              print SESSION (my $s = localtime);
              warn "Connection from [",inet_ntoa($hisaddr),",$port] finished\n";
              close SESSION;
              exit 0;
          }else {
              print "Forking child $pid\n";
          }
    }
    
    close SOCK;
    
    利用上述tcp_socket_cli.pl访问该server的执行结果:
    
    Starting server on port 3000...
    Connection from [127.0.0.1,32888]
    Connection from [127.0.0.1,32888] finished
    Reaped child 13927
    Forking child 13927