Socketに関して
SocketでURLで指定されたバナーを一旦ダウンロードし、
画像サイズを取得するプログラムなのですが、
以下のソースでは、画像が存在するURLを指定しても
「バナ-画像が存在しません。バナ-URLを確認してください。」
となってしまいます。
どこが不具合なのか分かる方がいらっしゃれば教えて頂けないでしょうか?
サーバーは「land.to」です。
use Socket;
sub GetBannerSize{
#バナ-サイズ取得(sock接続)
my ( $url ) = @_;
my ( $host, $port, $path, $dir, $file, $base, $ext, $width, $height, $ipaddr, $sockaddr, $tmpimg, $data );
$url =~ /(http:)?(\/\/)?([^:\/]*)?(:([0-9]+))?(\/.*)?/;
$host = $3;
if ($host eq "" || $host eq $ENV{'SERVER_NAME'}) {$host = 'localhost';}
$path = $6;
if ($path eq "") {$path = '/';}
if ($path =~ /(.*)\/(.*)/) {
$dir = $1.'/';
$file = $2;
} else {
$dir = './';
$file = $path;
}
if ($file =~ /(.*)\.(.*)/) {
$base = $1;
$ext = $2;
} else { # 拡張子なし
$base = $file;
$ext = "";
}
$port = getservbyname("http", "tcp");
$ipaddr = inet_aton($host) || &error("host($host) not found.");
$sockaddr = pack_sockaddr_in($port, $ipaddr);
socket(SOCK, PF_INET, SOCK_STREAM, 0) || &error("socket error.");
connect(SOCK, $sockaddr) || &error("connect $host $port error.");
select(SOCK);
$|=1;
select(STDOUT);
print SOCK << "END_OF_DOC";
GET $path HTTP/1.0
Host:$host
Connection:close
END_OF_DOC
while(<SOCK>){
last if m/^\r\n$/;
}
$tmpimg = "";
if ($ext eq "gif") {
$tmpimg = "./temp/tmp.gif";
}elsif ($ext eq "jpg" || $ext eq "jpeg") {
$tmpimg = "./temp/tmp.jpg";
}elsif ($ext eq "png") {
$tmpimg = "/temp/tmp.png";
}else{
&error("画像形式が正しくありません。");
}
open(OUT,">$tmpimg");
while (<SOCK>) {
if ($_ =~ /<HTML>/i) { &error("バナ-画像が存在しません。バナ-URLを確認してください。"); }
print OUT $_;
}
close(OUT);
close SOCK;
$width = 0;
$height = 0;
if ($ext eq "gif") {
open(IN,"$tmpimg") || return (0,0);
binmode(IN);
sysread(IN,$data,10);
close(IN);
if ($data =~ /^GIF/) { $data = substr($data,-4); }
$width = unpack("v",substr($data,0,2));
$height = unpack("v",substr($data,2,2));
} elsif ($ext eq "jpg" || $ext eq "jpeg") {
local($t, $m, $c, $l);
open(IN,"$tmpimg") || return (0,0);
binmode(IN);
read(IN, $t, 2);
while (1) {
read(IN, $t, 4);
($m, $c, $l) = unpack("a a n", $t);
if ($m ne "\xFF") { $W = $H = 0; last; }
elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) {
read(IN, $t, 5);
($height, $width) = unpack("xnn", $t);
last;
}
else {
read(IN, $t, ($l - 2));
}
}
close(IN);
} elsif ($ext eq "png") {
open(IN,"$tmpimg") || return (0,0);
binmode(IN);
read(IN, $data, 24);
close(IN);
$width = unpack("N", substr($data, 16, 20));
$height = unpack("N", substr($data, 20, 24));
}
unlink $tmpimg;
return( $width, $height );
}
お礼
少々遅れましたが、ありがとうございました。 バッファリングに関する処理漏れだと気づくことが出来ました。
補足
回答ありがとうございます。 YAMAMAYAさんの仰る通りで、select SOCKET;$| = 1; を入れておらずバッファに溜まったままであったらしいです。 挿入したところ動くようになりました。 但し、 ■サーバ側 select SOCKET;$| = 1;select(STDOUT); $client=accept(C_SOCKET, P_SOCKET); while(<C_SOCKET>){ printf("%s",$_); #受信データ print C_SOCKET "Return Data!!\n"; #送信データ } →動く○ --------------------------------------- select SOCKET;$| = 1;select(STDOUT); $client=accept(C_SOCKET, P_SOCKET); while(<C_SOCKET>){ printf("%s",$_); #受信データ } print C_SOCKET "Return Data!!\n"; #送信データ →While文の外に出すと動かない× これについて何か分かりますか? 宜しくお願いします。