接收端代码:
use strict;
use IO::Socket;
use IO::Select;
use Socket;
use Compress::Zlib ;
my $port=2008;
my ($input,$no,$temp,$num,$n,$head,$input1,$input2,$i,$u,$z,$length,
$head,$r);
$z=0;
$num=10000;
#my $length=1400;
$input1='a'x90000000;
$input1='';
$temp='a'x90000000;
$temp='';
my $file="34567.exe";
open(FILE,">$file");
binmode FILE;
my $sock = IO::Socket::INET->new( Listen => 20,
LocalPort => $port,
Proto =>'TCP',
Reuse => 1)
or die "Can't create listening socket: $!\n";
print "recv sever is connect now!\n"; #创建一个服务器进行监听。
$no=1;
#确定保存文件全路径名并打开文件
my $session = $sock->accept();
my $select=IO::Select->new($session);
my $rr;
print "文件接收中...\n";
###########接收文件前的通信:依次按读出的长度读出 文件名 文件长度 SNDBUFF ####################
my ($l0,$l1,$l2,$l3,$cmd,$filename,$u,$buf,$info);
while(1){
if ($select->can_read()) {
if($session->recv($info,10000,0))
{
$l0=substr($info,0,1);
$l0=unpack("c",$l0);
#print $l0."\n";
$cmd=substr($info,1,$l0);
$l1=substr($info,$l0+1,1);
$l1=unpack("c",$l1);
#print $l1."\n";
$filename=substr($info,$l0+2,$l1);
#print $filename."\n";
$l2=substr($info,$l0+$l1+2,1);
$l2=unpack("c",$l2);
#print $l2."\n";
$u=substr($info,$l0+$l1+3,$l2);
#print $u."\n";
$l3=substr($info,$l0+$l1+$l2+3,1);
$l3=unpack("c",$l3);
#print $l3."\n";
$buf=substr($info,$l0+$l1+$l2+4,$l3);
#print $buf."\n";
$buf=pack("I", $buf);
setsockopt($sock, SOL_SOCKET, SO_RCVBUF, $buf);
$length=getsockopt($sock,SOL_SOCKET,SO_RCVBUF);
#print $length,"\n";
$length=unpack("I", $length);
$session->send("BEGIN");last;
}
}
}
while (1){
##################### ##################### #####################
#################### #####################
if ($select->can_read()) {
unless($filename=~/\.exe$/i or $filename=~/\.zip$/i or
$filename=~/\.rar$/i )
{
while(1) {
if( $session->recv($head,$length,0))
{ #print "$head\n";
$head=hex(substr(unpack("H*",$head),0,8));
#print "$head\n";
$session->send("START");last;}
}
}
RE: $r=sysread $session,$input,$length;
#print "$n\n";
$input1.=$input;
$i=length $input1;
#print $i." ".$head."\n";
unless($filename=~/\.exe$/i or $filename=~/\.zip$/i or
$filename=~/\.rar$/i )
{unless($i eq $head){goto RE;}}
unless($filename=~/\.exe$/i or $filename=~/\.zip$/
i or $filename=~/\.rar$/i )
{$input1=uncompress($input1);}
$z+=$i;
#print $z."\n";
$temp.=$input1;
unless($filename=~/\.exe$/i or $filename=~/\.zip$/i or
$filename=~/\.rar$/i )
{ }
else
{ if($no%$num==0)
{
print FILE $temp;
$temp="";
}
}
if ($z eq $u) {
if($filename=~/\.exe$/i or $filename=~/\.zip$/i or $filename=~/
\.rar$/i )
{print FILE $temp; }
close(FILE);
shutdown $session,2;
print "接收完毕\n";
exit(0);
}
$no++;
$input="";$input1="";
unless($filename=~/\.exe$/i or $filename=~/\.zip$/i or
$filename=~/\.rar$/i )
{$temp="";}
##################### ##################### #####################
##################### #####################
}
}
发送端代码:
use strict;
use IO::Socket;
use IO::Select;
use Socket;
use Compress::Zlib ;
my $ss; my $mm; my $hh;
my $n;my $t;my $w;
my ($host,$port,$line,$f,$sock,$head,$headpack,$sum1);
print "####飞鸽传书模拟版,文件发送端###\n";
$host="192.168.1.100";#124.128.127.15 192.168.1.101
$port=2008;
#确定主机地址
my $path="123.exe";
#确定传送文件
&start_sock;
sub start_sock
{$sock=new IO::Socket::INET(PeerAddr=>$host,
PeerPort=>$port,
Proto =>'TCP'
) or die "connect err";
my $select=IO::Select->new($sock);
my $l =getsockopt($sock,SOL_SOCKET,SO_SNDBUF);
$l=unpack("I", $l);
my $length=$l*1000;#可以改变大小(每一大块数据的大小)
print "sock creat ok!\n";
my $time= scalar(localtime);
print "开始发送时间:".$time."\n";
$time=substr($time,11,8);
my @time=split/:/,$time;
my $h=$time[0];
my $m=$time[1];
my $s=$time[2]; #取时间
print "开始发送...\n";
my $session;
my $input;
my $f_content;
open(FILE,$path) or die "open file err";
my $no=1;
my $sum;
binmode FILE;
my $size = (stat($path))[7];
#print $size."\n";
if ($size%$length==0) {
$sum=$size/$length;
}
else {
$sum=int($size/$length+1);
} # 取文件大小,确定发送数据包的个数
###########接收文件前的通信:依次发送: 命令长度, 命令行(以后扩展用), 文件名长度, 文件名, 文件大小长度, 文件大小,
SENDBUFFER长度, SENDBUFFER.####################
my $cmd="0000";#定义命令 以后扩展
my $length0=length $cmd;#命令长度 以后扩展
$length0=pack("c",$length0);
my $length1=length $path;
$length1=pack("c",$length1);
my $length2=length $size;
$length2=pack("c",$length2);
my $length3=length $l;
my $length3=pack("c",$length3);
print $sock $length0.$cmd.$length1.$path.$length2.$size.$length3.$l;
AA:if ($select->can_read()) {
sysread $sock,$input,5;
if($input eq "BEGIN"){goto CC;}
else{ goto AA;}
}
else{ goto AA;}
#####################################组织发送数据:发送数据包的格式: 压缩数据大小
###################################################
########压缩数据方式:把原始数据分成很多较大的数据包,每一个大的数据包进行压缩
CC: foreach (1..$sum){
sysread FILE,$f_content,$length;
$w=0;
unless($path=~/\.exe$/i or $path=~/\.rar$/i or $path=~/\.zip$/i)
{$f_content=compress($f_content);
$head=length $f_content;
#print "$head\n";
$headpack=pack("N2",$head);
print $sock $headpack;
BB:if ($select->can_read()) {
sysread $sock,$input,5;
if($input eq "START"){goto DD;}
else{ goto BB;}
}
else{ goto BB;}
DD: if ($head%$l==0) {
$sum1=$head/$l;
}
else {
$sum1=int($head/$l+1);
}
}
else{$sum1=($length/$l);}
foreach(1..$sum1){
my $no1= pack("N2",$no);
if(!(substr($f_content,(0+$w*$l),$l))) {last;}
print $sock substr($f_content,(0+$w*$l),$l);#发送数据
#print "send : ".substr($f_content,0+$w*$l,1).substr($f_content,0+
$w*$l+1300,1)."\n";
$w++;
$no++;
}
#print "发送完毕\n";
}
########################################################################### #######################
#print "传送完毕\n";
my $time1= scalar(localtime);
print "发送完毕时间:".$time1."\n";
$time1=substr($time1,11,8);
my @time1=split/:/,$time1;
my $h1=$time1[0];
my $m1=$time1[1];
my $s1=$time1[2];
#取发送完毕的时间
if($s1 >= $s)
{$ss=$s1-$s;}
else
{$s1+=60;$ss=$s1-$s;$m1--;}
if($m1 >= $m)
{$mm=$m1-$m;}
else
{$m1+=60;$mm=$m1-$m;$h1--;}
if($h1 >= $h)
{$hh=$h1-$h;}
else
{$h1+=24;$hh=$h1-$h;}
print "发送消耗时间:$hh小时$mm分$ss秒\n";
#计算消耗时间
my $ts=$mm*60+$ss;
eval{print "平均".($size/$ts)/(1024*1024)."M/s\n";};
close(FILE);
shutdown $sock,2;
|