• ベストアンサー

socket経由でHTMLを表示

するために test.pl: #!/usr/local/bin/perl use Socket; $addr=(gethostbyname("www.ndl.go.jp"))[4]; $name=pack("S n a4 x8",2,80,$addr); socket(S,PF_INET,SOCK_STREAM,0); connect(S,$name); binmode(S); select(S);$|=1;select(stdout); print S "GET /index.html HTTP/1.1\n"; print S "Host:www.ndl.go.jp\n\n"; print "Content-type: text/html\n\n"; while(<S>){print;} close(S); をPerlが実行できるプロバイダのスペースにアップして Meのie6ブラウザからtest.plを表示させるとエラーになります どうしたらエラーを回避して "http://www.ndl.go.jp/index.html"(国立国会図書館) を表示することができるでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#9431
noname#9431
回答No.3

一番疑わしいのはNiftyが機能制限していることです。 質問欄のコードは正しくcgiの設置をすれば必ず動きます。 以前、確か、gethostbynameも機能制限うけているという結論になった御質問をしてませんでしたっけ? そもそも、Socketモジュール自体使えないようになっているのかもしれません。 use Socket; ですでにエラーになるのでは?

guuman
質問者

お礼

ありがとうございます gethostbynameも使えません いろいろ制限されていて大変です 明日Niftyに聞いて見ます

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • Ethersky
  • ベストアンサー率71% (168/235)
回答No.4

NiftyではPerlの標準モジュールは一切使えません。(標準がだめなら標準で入っていないモジュール類ももちろん用意されていません) http://homepage.nifty.com/cgi/index.htm?d_cgi1 ここの下にある「ご注意」の2番目に書いてあります。 (文書的にはjcode.pl等がないだけに思えますが実はSocket.pm等Perlに標準添付されているはずのモジュール類も用意されていません)

guuman
質問者

補足

ありがとうございます Niftyに電話するとやってうまくいかなければできないと判断するしかないとのことです そこでFedoraCore3のPCを使いたいのですが 外にアクセスに行くとエラーになります 具体的には #!/usr/local/bin/perl print "Location:http://hpcgi.nifty.com/x.pl\n\n"; のように外側のPerlCGIに移動しようとするとエラーになります 何か設定がいるのでしょうか? 同一PC同一ディレクトリにあるPerlCGIを使う分にはエラーにはなりません なおPHPから外部のPerlCGIに移動することはできます

全文を見る
すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

どんなエラーがでているのかわからないのでナンですが、サーバーからのGETに対するメッセージ HTTP/1.1 200 OK Date: Sun, 06 Feb 2005 09:05:29 GMT Server: Apache Last-Modified: Fri, 04 Feb 2005 01:20:28 GMT ETag: "5804c-2f71-49aa2f00" Accept-Ranges: bytes Content-Length: 12145 Content-Type: text/html がエラーを起こしているのではないでしょうか? そこで、 while(<S>){print;} の部分を <!DOCTYPEから</HTML>までを表示するということで while(<S>){ print if m|<!DOCTYPE|..m|</HTML>|; } としてみたらどうでしょう?

guuman
質問者

補足

ありがとうございます #!/usr/local/bin/perl use Socket; $addr=(gethostbyname("www.ndl.go.jp"))[4]; $name=pack("S n a4 x8",2,80,$addr); if(!socket(S,PF_INET,SOCK_STREAM,0)) { print "Content-type: text/html\n\n"; print "out1<br/>"; exit; } if(!connect(S,$name)) { print "Content-type: text/html\n\n"; print "out2<br/>"; exit; } binmode(S); select(S);$|=1;select(stdout); print S "GET /index.html HTTP/1.1\n"; print S "Host:www.ndl.go.jp\n\n"; print "Content-type: text/html\n\n"; while(<S>){print if m|<!DOCTYPE|..m|</HTML>|;} close(S); でやりましたが Niftyプロバイダサーバでやっているのでエラーの詳しいメッセージが出ません 実行エラー CGIの実行時にエラーが発生しました 。 というそっけないメッセージがNiftyのロゴを従えてブラウザ画面に表示されます 基本的に送り方を間違えていることは無いのでしょうか? コマンドラインではうまくいってますが コマンドライン実行用スクリプトをそのまま使っても大丈夫なのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

まずは、スクリプトのどこでエラーになっているかを確定するために、各関数の戻り値チェックなどのコードを追加してみては。 ぜんぜんエラーハンドリングがされてないようですので。 それとプロバイダに、サーバから外部への接続を許可しているかを確認すべきかと。 もしかすると追加料金が必要なのかも。

guuman
質問者

補足

ありがとうございます # #!/usr/local/bin/perl use Socket; $addr=(gethostbyname("www.ndl.go.jp"))[4]; $name=pack("S n a4 x8",2,80,$addr); socket(S,PF_INET,SOCK_STREAM,0); connect(S,$name); binmode(S); select(S);$|=1;select(stdout); print S "GET /index.html HTTP/1.1\n"; print S "Host:www.ndl.go.jp\n\n"; # print "Content-type: text/html\n\n"; while(<S>){print;} close(S); のように質問のコードから2行を取り除いたものが クライアントパソコンのドスプロンプトで perl test.pl を実行したら動きます そこで2行を追加してプロバイダサーバにアップして クライアントパソコンブラウザからアクセスしました そこでエラーが出ます test.plは実行属性にはしてます 明日プロバイダに聞いてみます

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • socketを使用したスクリプトがうまく動きません

    お世話になります。教えて!gooを初めて利用する者です。 Perlは本などを見ながら何とか動かせるレベルです。 この度、socketを使って他サイトを読み込む実験をしてみたところ、以下のコードでGoogleのトップページは読み込めましたがYahoo!のトップは何度やってもちゃんと読み込めません。 失敗している部分は、相対パス指定になっている部分のようです。 リンクや画像など、「http://www.yahoo.co.jp/~」となるはずのところが、「http://127.0.0.1/~」となってしまっています。 また、LWPモジュールというものも試してみましたが、こちらはGoogleのトップの読み込みも失敗しました。症状は上と同じです。 コードは本や有名サイトからそのまま引用してもダメで、多少いじってもやはりダメでした。 一人で解決するのは限界だと思いましたので、分かる方いらっしゃいましたらご助言をお願いいたします。 (試したコードの例↓) use Socket; $addr = (gethostbyname("www.google.co.jp"))[4]; $name = pack("S n a4 x8", 2, 80, $addr); socket(S, PF_INET, SOCK_STREAM, 0) || die "socket"; connect(S, $name) || die "connect"; binmode(S); select(S); $| = 1; select(STDOUT); print S "GET / HTTP/1.0\r\n\r\n"; while (<S>) { print; } close(S);

  • socketを使って外部のファイルを呼び込む

    $Host = 'abc.hogehoge.co.jp'; $Page = "/test_order.cgi?pass=1234&id=1234' $Addr = (gethostbyname($Host))[4]; $Name = pack("S n a4 x8", 2, 443, $Addr); socket(S, 2, 1, 0); connect(S, $Name); binmode(S); select(S); $| = 1; select(stdout); print S "GET $Page HTTP/1.0\r\n\r\n"; $Data = ''; while (<S>){ $Data = $_; } close(S); print"$Data"; 現在ある決済システムを組み込もうとしております。 上のように外部ホストのアクセスしてパスワードやID、その他あるのですがそれで接続していてもどうにも$Dataに出力されません。 print S "GET $Page HTTP/1.0\r\n\r\n"; とありますが外部ファイルはhtmlファイルではありません。たんなるテキスト文字が出力されるはずです。 直接ブラウザに https://abc.hogehoge.co.jp/test_order.cgi?pass=1234&id=1234' とたたくとテキストが出力されます。 なにかまちがっているのでしょうか? 恐れ入りますがご教授お願いします

    • ベストアンサー
    • CGI
  • perlのソケット通信について

    perlのソケット通信でwebブラウザーのようなものを製作中なのです。 http://tohoho.wakusei.ne.jp/wwwperl2.htm#socketを参考にしたのですが、 yahooは表示されますが、xrea系のサイトのような特定のサイトが閲覧できず(どちらかというと特定のサイトのみ閲覧できる)、NotFoundかDNSエラーになります。 とほほのWWW入門のサンプルの他に追加する項目などはあるのでしょうか?よろしくお願いします。 現在の構文は以下の通りです browser.cgi 改行コードLF、漢字コードEUC ------------- #! /usr/bin/perl print "Content-type:text/html\n\n"; $addr = (gethostbyname("www.xrea.com"))[4]; $name = pack("S n a4 x8", 2, 80, $addr); socket(S, 2, 1, 0); connect(S, $name); binmode(S); select(S); $| = 1; select(stdout); print S "GET /index.php HTTP/1.0\n\n"; while (<S>) { print; } close(S);

    • ベストアンサー
    • Perl
  • ソケットの使い方が分からない

    ので動作を見るためにとほほを見て WidnowsMeで x.pl: use Socket; $addr=(gethostbyname("www.ndl.go.jp"))[4]; $name=pack("S n a4 x8", 2, 80, $addr); socket(S,PF_INET,SOCK_STREAM,0); connect(S, $name); binmode(S); select(S); $|=1; select(stdout); print S "GET index.html HTTP/1.0\r\n\r\n"; while(<S>){print;} close(S); を作り perl x.pl を実行すると HTTP/1.1 400 Bad Request Date: Fri, 04 Feb 2005 15:40:15 GMT Server: Apache Content-Length: 226 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> </body></html> が帰ってきました なお http://www.ndl.go.jp/index.html は国立国会図書館のページでブラウザのアドレス欄に入れると正常に見れます どのように修正すればよいでしょうか?

    • ベストアンサー
    • Perl
  • SOCKETで入手したデータを抜き出したい

    他サーバのHTMLから部分的に抜き出したいと思っています。 他サーバのHTMLを表示する所までは出来たのですが、抜き出す所が出来ずに困っています。 私が抜き出そうと、表示のwhile文内を下記に変えた所、何も表示されなくなりました。  if( $_ =~ m/抜き出したい頭のキーワード/ ){ $flag = 1;}  if( $_ =~ m/表示したい尾のキーワード/ ){ $flag = 0;}  if( $flag eq 1){ print $_;} このwhile文内には変数に代入するとどうもNGのようです。 教えてGooの過去ログにも同様の質問があったのですが、 解決に至っていませんでした。ご教示願います。 ↓現在のソースコード ---------------------------- #!/usr/local/bin/perl -w use strict; use Socket; # Socket モジュールを使う # 接続先ホスト名 my $host = 'www.xxxx.co.jp'; # HTTP プロトコルを使う my $port = getservbyname('http', 'tcp'); # ホスト名を、IP アドレスの構造体に変換 my $iaddr = inet_aton($host) or die "$host は存在しないホストです。\n"; # ポート番号と IP アドレスを構造体に変換 my $sock_addr = pack_sockaddr_in($port, $iaddr); # ソケット生成 socket(SOCKET, PF_INET, SOCK_STREAM, 0) or die "ソケットを生成できません。\n"; # 指定のホストの指定のポートに接続 connect(SOCKET, $sock_addr) or die "$host のポート $portに接続できません。\n"; # ファイルハンドル SOCKET をバッファリングしない select(SOCKET); $|=1; select(STDOUT); # WWW サーバに HTTP リクエストを送る print SOCKET "GET /index.html HTTP/1.0\r\n"; print SOCKET "\r\n"; # ヘッダ部分を受け取る while (<SOCKET>){ # 改行のみの行ならループを抜ける m/^\r\n$/ and last; } # ボディ部分を受け取り、表示 while (<SOCKET>){ print $_; }

    • ベストアンサー
    • Perl
  • 標準出力と標準エラー出力を時系列にファイルへ

    例として、perlなどで、(test.plとします)  print "stdout1\n";  print STDERR "STDERR1\n";  print "stdout2\n";  print STDERR "STDERR2\n";  print "stdout3\n";  print STDERR "STDERR3\n"; このように、標準出力と、標準エラー出力が混在した状態の処理があった場合、 コマンドプロンプト(Windows2000)にて、 C:\>test.pl とすると、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のように時系列に出力されますが、これをログファイルに取ろうとして、 C:\>test.pl 1>log.txt 2>&1 とすると、 C:\>cat log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のように、標準エラー出力が先に吐き出されてしまいます。 これを画面出力時と同様に時系列で取れるようにしたいのですが、どのようにすれば良いでしょうか? 単純なことで困っています。よろしくお願いします。

  • DBD::Mysql が使用する標準のsocketはどこから得ているか?

    以下のようなスクリプトで、以下のようなエラーになっています。 port(socket)を指定しているにもかかわらず使用されない理由も分からないのですが、エラーメッセージのsocketはどこで設定されているのでしょうか? /etc/my.cnf で /tmp/mysql.sock を指定し、サーバーとクライアントは問題なく通信できています。 よろしくお願いします。 ■perlスクリプト ---------------------------------------- #!/usr/local/bin/perl use DBI; $user = 'usr'; $passwd = 'password'; $ds = 'DBI:mysql:db_name;host=localhost;port=/tmp/mysql.sock'; $db = DBI->connect($ds, $user, $passwd); (以下略) ■perlスクリプトのエラー ---------------------------------------- $ ./script_name.pl DBI connect('db_name;host=localhost;port=/tmp/mysql.sock','root',...) failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) at ./script_name.pl line 9 ■環境 ---------------------------------------- mysql:バイナリの(rpmでないやつ)4.0.24-standard OS:Linux 2.4.20-31.9(REDHAT) DBD:DBD-mysql-2.9004

    • ベストアンサー
    • Perl
  • socket通信でレスポンスを受け入れないようにするにはどうすればいいですか?

    socket SOCKET,2,1,0; select((select(SOCKET),$|=1)[0]); connect(SOCKET,pack('Sna4x8',2,80,scalar(gethostbyname('www.test.test')); print SOCKET "GET /test.cgi HTTP/1.1\r\n\r\n"; こんな感じでhttp://www.test.test/test.cgiをリクエストしているのですが、結果がわかっているので、レスポンスが必要ありません。 どうもリクエストが終わると<SOCKET>を実行しないでも勝手にレスポンスをサーバから読み込んでいるみたいです。 (なのでリクエストを送った後、ある程度の時間をおいてオフライン状態にしても<SOCKET>からレスポンスを読み取れます) レスポンスの結果は分かっているので読み込みたくないのですが、どうすればいいのでしょうか?

  • ITです。早速ですがwinsockでURLを指定した接続確認をしたいの

    ITです。早速ですがwinsockでURLを指定した接続確認をしたいのですが、うまくいきません。 下記のソースで、URLを指定してinet_addr関数呼び出すと-1、 gethostbynameを呼び出すと0が却ってきてしまい、うまく接続出来ません。 IPアドレス(127.0.0.1)を指定すれば、上記の関数は成功するのですが。 URLからIPアドレスの変換方法が解りません。 どうか助けて下さい。 int main(int argc, char* argv[]) { WSADATA wsaData; sockaddr_in server; SOCKET sock; long err; hostent *host; char *url = "http://www.yahoo.co.jp"; // winsock2の初期化 err = WSAStartup(MAKEWORD(2,0), &wsaData); if (err != 0) { printf("WSAStartup error = %d\n", err); return(-1); } // ソケットの取得 sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { printf("socket error = %d\n", WSAGetLastError()); return(-1); } // IPアドレスの取得 memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(80); server.sin_addr.S_un.S_addr = inet_addr(url); if (server.sin_addr.S_un.S_addr == -1) { host = gethostbyname(url); if (host == NULL) { printf("host not found host = %d\n", WSAGetLastError()); return(-1); } }

  • 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 ); }

このQ&Aのポイント
  • 双極性障害II型の軽躁状態の時に、家族や友人に対して鬱陶しく感じたり遠ざけたくなることは考えられますか?友人の態度が変わったため戸惑っています。
  • 鬱状態の時には支えてきたつもりですが、友人が急に自分にやらなければいけないことがあると説明し、連絡を取らなくなりました。友人の気持ちや人間関係について悩んでいます。
  • また、友人が再び鬱状態に落ちた時に、人間関係を切ってしまったことを後悔するのかどうかも気になっています。
回答を見る

専門家に質問してみよう