indyを使うプログラムを多重起動するためには?

解決


altlegend  2011-03-31 22:49:25  No: 40352  IP: 192.*.*.*

今晩は。
今悩んでいることが2つあるのですが、1つを質問させてください。

delphi7で作ったプログラムを2009でコンパイルしているのですが、
Indyを使ったプログラムを多重起動するとIOエラーになります。
これを防止する方法ってありますか?

よろしくお願いします。

編集 削除
igy  2011-04-01 00:15:14  No: 40353  IP: 192.*.*.*

エラーが発生するのは、ソースコードのどの部分ですか?

編集 削除
altlegend  2011-04-01 20:26:00  No: 40354  IP: 192.*.*.*

こんばんは。
igyさん、ありがとうございます。
どこでエラーが出るかは調べることができませんでした。
昔のBASICのon  erro  go  toみたいなのは無いんですかね。
しかし、考えられるのはこれしかないと思います
もう一つこれを使うプログラムがあって、それは多重起動しても動くんですが。
よろしくお願いします。

procedure HtpDataGet(Var ReadBuff : String; FURL : String; Inte:integer);
var
  S:String;
  i:integer;
  sL:TstringList;
  MST:TMemoryStream;
  ENC:TEncoding;
begin
 with Form1 do begin
  ENC :=TMBCSEncoding.Create(inte);
  MST :=TMemoryStream.Create;
  sL:=TstringList.Create;
  try
    IdHTTP1.Get(FURL,MST);
    MST.Position :=0;
    SL.LoadFromStream(MST,ENC);
    for I := 0 to SL.Count - 1 do s:=s+sL[i]+#$0A;;
  finally
    ENC.Free;
    MST.Free;
    SL.Free;
  end;
  ReadBuff :=s;
 end;
end;

編集 削除
HOta  2011-04-01 21:07:19  No: 40355  IP: 192.*.*.*

Try exception end;
がありますよ。
これはon  erroなどより強力です。

編集 削除
igy  2011-04-01 21:13:40  No: 40356  IP: 192.*.*.*

>どこでエラーが出るかは調べることができませんでした。

>しかし、考えられるのはこれしかないと思います

新規プロジェクトに、挙げられたソースコートとTIdHttpなど最小限のものを追加した場合でも、
エラーは表示しますか?

編集 削除
altlegend  2011-04-01 22:36:13  No: 40357  IP: 192.*.*.*

今晩は。

早速、ありがとうございます。

Hotaさん、2009ではexceptionは出ないようです。
tryとうつと,finally  end;が出ます。
7でも使えないようですが、確かに以前は使ったような気がしましたが。
使い方が悪いですかね。

igyさん、最小限のものではちょっと再現は難しいような気がします。
ちょっと書きましたが、このHtpDataGetの使用の頻度が少ない別のプログラムでは、あまりIOエラーは出ないんです。
5個立ち上げてやってみて、1個がIOエラーになりました。
10個立ち上げたら5個エラーが出ました。

この問題の出るプログラムはこれを遣いまくるプログラムでして、2個の多重起動ですぐ出ます。

もう一つの悩みは何とか解決しました。
長い間使ってきたプログラムで、おかしいところを直してもエラーが消えなくて相当悩んでいました。
結果的には、古いフォルダーのフォームを参照していたようです。

編集 削除
igy  2011-04-01 23:10:50  No: 40358  IP: 192.*.*.*

>igyさん、最小限のものではちょっと再現は難しいような気がします。

では、再現できるようなソースコードを作ってみて
ここに挙げてみるのははいかがですか?

編集 削除
KHE00221  2011-04-01 23:19:41  No: 40359  IP: 192.*.*.*

BDS 2006 だが

procedure TForm3.Timer1Timer(Sender: TObject);
begin
    Memo1.Lines.Text := IdHTTP1.Get('http://www.yahoo.co.jp/');
end;

を20個起動してもエラーはおきない

Interval = 1000

編集 削除
KHE00221  2011-04-01 23:27:18  No: 40360  IP: 192.*.*.*

XE で20個起動してもエラーは出ない

procedure TForm1.Timer1Timer(Sender: TObject);
var
    S: String;
begin
    HtpDataget (S,'http://www.yahoo.co.jp',0);
    Memo1.Lines.Text := S;
end;

編集 削除
igy  2011-04-02 00:21:57  No: 40361  IP: 192.*.*.*

あと、関係ないかもしれませんが確認を・・・

・Delphi2009は最新のアップデートまで適用されていますか?
・使用しているIndyは標準搭載しているものですか?
  あるいは、ダウンロードしてインストールしたものですか?
・OSは何ですか?

それと、

単独でエラーが出ず、多重起動のときのみ

> IOエラーになります。

のであれば、例えば、片方がファイルを書き込み中とかで開いている状態で、
もう片方が同じファイルに書き込もうとしていたりとかはありませんか?

編集 削除
aoba  2011-04-02 05:03:07  No: 40362  IP: 192.*.*.*

> 2009ではexceptionは出ないようです。
> tryとうつと,finally  end;が出ます。
> 7でも使えないようですが、確かに以前は使ったような気がしましたが。

それはコードの自動補完で出るだけですよね?
そもそもexceptionというのは間違いで、正しくはexceptですが、
try exceptというのは大昔からある基本的な例外機構のひとつです。
http://docwiki.embarcadero.com/RADStudio/ja/%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%E6%96%87

失礼ですが、これを知らないのであれは中級者ではなく初心者を名乗られた方が良いのではないでしょうか。
質問者が初心者と名乗られている場合、回答者は根本的な部分から説明するように心がけますが、
中級者と名乗られている場合、回答者も相応の知識があるものと思って回答しますから。

編集 削除
altlegend  2011-04-02 07:28:55  No: 40363  IP: 192.*.*.*

皆さん、ありがとうございます。

中級者を名乗っているのは、前にも書きましたが、
delphiで10年近くプログラムしているからです。
中身は素人です。

exceptはありがとうございます。以前というのは10年前という意味ですので、exceptとexceptionと区別はつきませんでした。
これで、早速試してみます。

保存のエラーではという件では、同じプログラムで保存場所を変えて実行してもIOエラーがでました。

例としては、次のような感じですね。
試してみると、別のエラーですが、出まくりました。
確かにIOエラーはでませんでした。
別の所にミスがあるかもですね。
調べて見ます。
ありがとうとうございました。


procedure TForm1.Timer1Timer(Sender: TObject);
var
    S: String;
    i:integer;
begin
  i:=0;
  repeat
    inc(i);  s:='';
    HtpDataget (S,'http://www.yahoo.co.jp',0);
  until i>1000000
  Memo1.Lines.Text := S;
end;

編集 削除
altlegend  2011-04-02 07:45:01  No: 40364  IP: 192.*.*.*

igyさん、ありがとうございました。

IOエラーは入出力のエラーということをわすれてました。

編集 削除
igy  2011-04-02 10:12:24  No: 40365  IP: 192.*.*.*

> 試してみると、別のエラーですが、出まくりました。

>  repeat
>    inc(i);  s:='';
>    HtpDataget (S,'http://www.yahoo.co.jp',0);
>  until i>1000000

実在するサイトで100万回もテストしないようがよいと思います。

編集 削除
igy  2011-04-02 10:13:52  No: 40366  IP: 192.*.*.*

訂正です。
×:実在するサイトで100万回もテストしないようがよいと思います。
○:実在するサイトで100万回もテストしないほうがよいと思います。

編集 削除
monaa  2011-04-02 14:07:43  No: 40367  IP: 192.*.*.*

テストコードみて噴いた!
意図せずだと思いますが、完全にアタック系ソフトですね。
このテスト続けたらアクセス遮断されそう。

編集 削除
altlegend  2011-04-02 19:48:47  No: 40368  IP: 192.*.*.*

こんばんは。

いや、これは使用頻度を表現しただけで、アタック系ではないですよ。
同じ所にアクセスするんじゃないですし。
ホームページはどんどん変えていきますので。
まあ、初めて作ったときは「これ攻撃と同じじゃん」と思いましたが。

実際、年に1回は(昔は)1日以上かけて、10個くらい多重起動して、トータルでは50万回くらいアクセスしていましたね。
今は光通信で早くなりましたけどね。
昨年末はADSLでしたが、結構早いなと思いましたね。
その多重起動ができないので焦りました。

一応、もう質問はなくなりました。
2009で完全にコンパイルできました。

皆さん、本当にありがとうございました。

編集 削除
igy  2011-04-02 21:27:08  No: 40369  IP: 192.*.*.*

>いや、これは使用頻度を表現しただけで、アタック系ではないですよ。
>同じ所にアクセスするんじゃないですし。

でも、

>例としては、次のような感じですね。
>試してみると、別のエラーですが、出まくりました。

>  repeat
>    inc(i);  s:='';
>    HtpDataget (S,'http://www.yahoo.co.jp',0);
>  until i>1000000

のように、同じ所にアクセスする例を提示し、“試してみると”と書かれる

>実在するサイトで100万回もテストしないほうがよいと思います。

と書きたくなりますよ。

編集 削除
igy  2011-04-02 23:34:33  No: 40370  IP: 192.*.*.*

技術系メーリングリストで質問するときのパターン・ランゲージ
http://www.hyuki.com/writing/techask.html

は、メーリングリスト向けで書かれていますが、この掲示板でご質問される場合にも
参考になるかと思います。参考までに・・・

(中級者の方にとっては、すでにご存知のことばかりかもしれませんが・・)

編集 削除
altlegend  2011-04-03 00:59:08  No: 40371  IP: 192.*.*.*

こんばんは。

igyさん、そうですね。
実際エラーが出るか試したわけですからね。
まあ気をつけたいと思います。

メーリングリストの件も参考になります。
中級者と言っても実際は素人ですから。

また、よろしくです。

編集 削除
素人≠中級者  2011-04-04 19:01:12  No: 40372  IP: 192.*.*.*

何か勘違いなさってると思いますが、
長年使っているから中級者ということにはなりません。
あくまでもスキルがどれだけあるかということですから、
20年やっても50年やっても素人同然であれば初心者です。

すでに他の方も書かれていますが、問題なのはどの程度の知識があるかであり、
あなたが何年プログラミングをやっているかはどうでも良いことです。
初心者ならば初心者と書いていただいた方が適切な回答が出来ます。
igyさんが提示されたサイトをご覧になったのであれば、
何故素人が中級者と名乗ってはいけないのかがよくわかるはずですが。

編集 削除
igy  2011-04-05 00:15:57  No: 40373  IP: 192.*.*.*

>igyさん、ありがとうございました。
>
>IOエラーは入出力のエラーということをわすれてました。

問題の部分・原因は何だったのですか?

編集 削除
altlegend  2011-04-22 23:36:53  No: 40374  IP: 192.*.*.*

すみません。

解決とチェックしましたが、やはり多重起動はできません。
2つ立ち上げると、かなりの確率で1つは止まります。
3つ立ち上げると、動くのは最後のものだけです。

何とかできないでしょうか。

プログラムは、先に書いた100万回ダウンロードするプログラムをダウンロード先を変えて並列起動するのと似ていると思います。
まあ、ものすごく複雑ですけどね。

igyさん、最初のほうのミスはチェック用の出力が消えてない古い分がコンパイルされていました。

編集 削除
igy  2011-04-23 00:02:14  No: 40375  IP: 192.*.*.*

>解決とチェックしましたが、やはり多重起動はできません。
>2つ立ち上げると、かなりの確率で1つは止まります。
>3つ立ち上げると、動くのは最後のものだけです。
>
>何とかできないでしょうか。

“できません” とか “止まります”では、これを見ている人は、
判りません。

エラーが表示する場合、そのメッセージを可能な限り正確に、
ここに提示してみるのはいかがですか?

また、それが起こるソースコードの場所を特定してみて
ここに提示してみるのはいかがですか?

あるいは、再現できるようなソースコードを作ってみて
ここに挙げてみるのははいかがですか?

繰り返しになりますが、

技術系メーリングリストで質問するときのパターン・ランゲージ
http://www.hyuki.com/writing/techask.html

はご覧になられましたか?

編集 削除
altlegend  2011-04-25 08:12:02  No: 40376  IP: 192.*.*.*

igyさん、ありがとうございました。

再現できるかということで、下のようなプログラムを作り、8個起動して試してみました。
それぞれが200回以上になるまでは順調に作動しましたが、220回とかになると順次、socket error #10060 connection time out というエラー表示を出して止まりました。最後までいけたのは1個だけでした。

100万回は無茶だと言われましたので今回は1000回にしました。

HtpDataGetは上にありますので、1度試してもらいたいです。

windowsvistでdelphi2009を使ってます。光通信です。

procedure TForm4.Button1Click(Sender: TObject);
var
  s: String;
  i:integer;
begin
  i:=0;
  repeat
    inc(i);
    s:='';
    richedit1.lines.clear;
    edit1.text:=inttostr(i);
    HtpDataget (S,'http://www.yahoo.co.jp',0);
    if (i mod 10)<5 then richedit1.Lines.Text := S;
    Application.ProcessMessages;
  until i>1000;
end;

編集 削除
altlegend  2011-04-25 08:27:17  No: 40377  IP: 192.*.*.*

上の続きです。

以前は、下記の様なプログラムでHPをダウンロードしていましたが、文字化けするようになったので,Indyに変えました。
このときは、8個多重起動して、問題なく作動していました。
この部分を上のHtpDataGetを変えただけで、多重起動ができなくなりました。

      html1 := TBaseHtml.Create;
      htmlNum := html1.GetHtml(StrHTTP, PROXY_NO_USE);
      S:='';
      for k := 0 to htmlNum-1 do S:=S+html1.GetHtmlList(k);
      html1.free;

編集 削除
Quest  2011-04-25 12:25:01  No: 40378  IP: 192.*.*.*

>この部分を上のHtpDataGetを変えただけで、多重起動ができなくなりました。
多重起動ができなくなったという事は、1つ起動すると2つ目からは起動も
できないという事ですよね?
流れからすると「起動はするがエラーが出る」という事でしょうか?
多重起動できない事と、多重起動できるが実行エラーになる事は違いますので。

また、TBaseHtmlって何でしょう?
>このときは、8個多重起動して、問題なく作動していました。
の「このとき」とはIndyに替える前ですか後ですか?
そのときもテストで同じURLに対してアクセスしたのでしょうか?

socket error #10060になる原因って、www.yahoo.co.jpへの経路の途中で
利口なルータやサーバーが、攻撃だと判断して遮断してしまったとかでは?
HtpDatagetをコールした後、Sleep(2000)とかしたらエラーは出ますか?
(当然時間は掛かりますので2000の部分はそれなりに)

たとえ回数を減らしたとしても、短期間(数秒?)に同じIPから1000回ですから(しかも×8)
やはり止めた方がいいんじゃないでしょうか。
テストしているPCにApacheなどインストールして自分自身にアクセスすれば
少なくとも経路上の問題かどうか切り分けられるし、何万回やろうとも
誰にも迷惑かけずに済みますよ。

編集 削除
altlegend  2011-04-26 06:18:47  No: 40379  IP: 192.*.*.*

おはようございます。

多重起動はできるんですが、エラーが出るという意味です。

TBaseHtmlを使っていたときはエラーも出ませんし、HPもダウンロードできていました。

>攻撃だと判断して遮断してしまったとかでは?
良くは分かりませんが、そういうことかもですね。
実際に自分のプログラムでは、3個起動したら2個は止まるだけでエラー表示は出ませんからね。
でも、1個は最後までできましたから、そういうことではないと思えますが。

開発当初,sleep(500)を入れていましたが、TBaseHtmlの時は入れなくても大丈夫だったので、削除しました。ものすごく時間がかかる原因になっていましたので。

Apaxheの件はよく分かりませんので研究してみます。

実際のプログラムでは同じ所は1回しかダウンロードしていませんので、攻撃とかでは決してありませんから、そのところはご理解願いますね。

編集 削除