- 论坛徽章:
- 27
|
本帖最后由 yifangyou 于 2011-02-27 16:22 编辑
- ####################################################
- #系统环境:centos 5
- #编译环境:v5.8.8 built for i386-linux-thread-multi
- #执行: perl 7.pl
- #题目:
- #7.让用户不断猜测范围从1到100的秘密数字,直到猜中为止。程序应该以魔术公式lnt(1+rand 100)来随机产生秘密数字。
- #当用户猜错时,程序应相应“too high”或者“too low”。
- #如果用户quit或者exit或者键入一个空白行程序就中止。当然如果用户猜到了,程序也应该中止。
- #
- ####################################################
- $min_number=1;
- $max_number=100;
- #获取随机数
- $rand_number=int($min_number+rand($max_number));
- print "program have create a randrom num between $min_number and $max_number,enter a number to guess it\n";
- print "or enter 'quit' or 'exit' or blank line to exit\n";
- $guess_time=0;
- while(<STDIN>){
- #获取输入并转小写
- $enter_str = lc($_);
- #去掉空白字符
- $enter_str =~ s/\s//g;
- #判断是否是整数
- if(!($enter_str=~/\d+/)){
- #判断是否退出
- if($enter_str eq "exit" || $enter_str eq "quit" || $enter_str eq ""){
- #退出
- print("sorry,you lose $guess_time times\n");
- die("exit ok\n");
- }
- print("please enter the number between $min_number and $max_number or enter 'quit' or 'exit' or blank line to exit\n");
- }else{
- $guess_time++;
- #判断是否相等
- if($enter_str==$rand_number){
- #相等则退出
- print("you win the number is $rand_number,you have guess $guess_time times\n");
- die("exit ok\n");
- }else{
- #提示输入的是大还是小
- if($enter_str > $rand_number){
- print("too high,you lose $guess_time times\n");
- }else{
- print("too low,you lose $guess_time times\n");
- }
- }
- }
- }
复制代码 第8题- #!/usr/bin/perl
- ####################################################
- #系统环境:centos 5
- #编译环境:perl, v5.8.8 built for i386-linux-thread-multi
- #执行: perl 8.pl 或者 perl 8.pl 1234 (端口)
- #题目:
- #8. 写一个简单的TCP Echo Server,在linux/unix环境运行,侦听在特定端口,接受用户的网络输入,并返回同样的数据给对方,能接受quit命令。
- #基本要求:
- #(1)无阻塞IO。
- #(2)daemon方式运行。
- #(3)能接受kill -HUP重启信号
- # 发送hup信号命令:kill -s hup 进程号
- #
- ####################################################
- #use POSIX ();
- use FindBin ();
- use File::Basename ();
- use File::Spec::Functions;
- use IO::Socket::INET;
- use IO::Select;
- use Carp;
- our $server;
- our $server_port=5555;#默认端口
- our $zombies = 0;
- our $script = File::Basename::basename($0);
- our $logfile="/tmp/8.log";
- our $read_handles;
- # 获取重新启动命令
- our $SELF = "perl ".catfile $FindBin::Bin, $script;
- our $isrestart=0; #标识是否重新启动
- $SIG{CHLD} = sub {$zombies++};
- $SIG{HUP} = sub {
- logs("get HUP,restart server");
- $isrestart=1;
- stopServer();
- };
- #从参数获取端口
- if(isPort($ARGV[0])){
- $server_port=$ARGV[0];
- }
- #deamon方式
- daemonize();
- #启动服务
- startServer();
- exit;
- #函数部分-----------------------------------------------
- sub isPort{
- my $port=shift(@_);
- if($port=~/d+/){
- #判断端口合法性,必须是整数,并且大于1024
- if($port > 1024){
- return $port;
- }
- }
- return 0;
- }
- #记录日志
- sub logs{
- my $msg=shift;
- open(LOGFILE,">>$logfile") or die("cannot open $logfile");
- my($sec,$min,$hour,$mday,$mon,$year)=localtime();
- print LOGFILE sprintf("%04d-%02d-%02d %02d:%02d:%02d ",($year< 2000?($year+1900):$year),($mon+1),$mday,$hour,$min,$sec),$msg,"\n";
- close(LOGFILE);
- }
- #deamon方式
- sub daemonize {
- chdir '/' or croak "Can't chdir to /: $!";
- open STDIN, '/dev/null' or croak "Can't read /dev/null: $!";
- open STDOUT, '>/dev/null' or croak "Can't write to /dev/null: $!";
- defined(my $pid = fork) or croak "Can't fork: $!";
- exit if $pid;
- setsid or croak "Can't start a new session: $!";
- open STDERR, '>&STDOUT' or croak "Can't dup stdout: $!";
- }
- # 停止或者重新启动server
- sub stopServer{
- $server->close();
- $read_handles->remove($server);
- # 清除所有的客户端
- foreach $fd ($read_handles->handles){
- $read_handles->remove($fd);
- close $fd;
- }
- logs("server shutdown");
- # 判断是否重新启动
- if($isrestart==1){
- $isrestart=0;
- # 重新启动
- logs($SELF, @ARGV);
- exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
- }
- exit; # 退出
- }
- # 启动server
- sub startServer{
- # 创建套接字
- $server = IO::Socket::INET->new(
- LocalPort => $server_port,
- Type => SOCK_STREAM,
- Reuse => 1,
- Listen => 10,# 或者 SOMAXCONN
- Blocking => 0)# 设置非阻塞
- or die "Couldn't be a tcp server on port $server_port: $!\n";
- $read_handles = IO::Select->new();
- $read_handles->add($server);
-
- local $| = 1;
- logs("server start ok binding port $server_port\n");
- my $fds;
- while (1) {
- ($fds) =IO::Select->select($read_handles, undef, undef,0 );
- foreach $fd ( @$fds ){
- if( $fd== $server ){
- if($server->opened){
- #server收到新的客户端连接
- my $client = $server->accept();
- $read_handles->add($client);
- }else{
- #server被关闭了
- stopServer();
- last;
- }
- }else{
- $msg = <$fd>;
- if($msg){
- #获取输入并转小写
- $enter_str = lc($msg);
- #去掉回车
- chomp $enter_str;
- # 判断是否退出
- if($enter_str eq "quit"){
- logs("server quit");
- stopServer();
- }
- $fd->print($msg);
- }else{
- # client has finished/closed
- $read_handles->remove($fd);
- close $fd;
- }
- }
- }
- }
- stopServer();
- }
复制代码- ####################################################
- #系统环境:centos 5
- #编译环境:perl, v5.8.8 built for i386-linux-thread-multi
- #执行: perl 8_client.pl 或者 perl 8_client.pl 127.0.0.1 5555
- #题目:
- #测试题目8的客户端,输入end:退出客户端;输入quit:发quit命令给服务端并退出客户端;
- #
- ####################################################
- use IO::Socket::INET;
- our $server_ip="127.0.0.1"; #默认IP
- our $server_port=5555; #默认端口
- $msg="Why don't you call me anymore?\n";
- #从参数获取server的ip
- if(isIP($ARGV[0])){
- $server_ip=$ARGV[0];
- }
- #从参数获取端口
- if(isPort($ARGV[1])){
- $server_port=$ARGV[1];
- }
- $socket = IO::Socket::INET->new(PeerAddr =>$server_ip,
- PeerPort => $server_port,
- Proto => "tcp",
- Type => SOCK_STREAM,
- Timeout=>1)
- or die "Couldn't connect to $server_ip:$server_port: $!\n";
- $socket->autoflush(1);
- print "enter something to send to server,enter 'quit' to shutdown server or enter 'end' to quit client\n";
- # 通过套接字发送某些东西,
- while(<STDIN>){
- #获取输入并转小写
- $enter_str = lc($_);
- #去掉回车
- chomp $enter_str;
-
- #判断是否退出
- if($enter_str eq "end" || $enter_str eq "quit" ){
- #退出客户端
- print "exit ok\n";
- if($enter_str eq "quit"){
- $socket->print($_);
- print "send ok:$_\n";
- }
- last;
- }
- $socket->print($_);
- print "send ok:$_\n";
-
- # 读取远端响应
- $answer = <$socket>;
- if($answer eq ""){
- last;
- }
- print "answer:$answer\n";
- }
- # 然后在结束之后终止联接。
- close($socket);
- sub isPort{
- my $port=shift(@_);
- if($port=~/d+/){
- #判断输入合法性
- if($port > 1024){
- return $port;
- }
- }
- return 0;
- }
- sub isIP {
- my $ip=shift(@_);
- if($ip=~/d{3}\.d{3}\.d{3}\.d{3}/){
- my @ipn=split(".",$ip);
- for my $n (@ipn){
- if($n > 255){
- return 0;
- }
- }
- }else{
- return 0;
- }
- return 1;
- }
复制代码 |
|