[#20083] non-block IO with TCPSocket — dn <daisuke@...>

初投稿の中村と申します。よろしくお願いします。

19 messages 2000/01/06
[#20084] Re: non-block IO with TCPSocket — Tomoyuki Kosimizu <greentea@...2.so-net.ne.jp> 2000/01/06

越水です。

[#20091] Re: non-block IO with TCPSocket — とみたまさひろ <tommy@...> 2000/01/06

とみたです。

[#20133] おききしたーいでーす — akimaru <akimaru@...>

17 messages 2000/01/09
[#20138] Re: おききしたーいでーす — akimaru <akimaru@...> 2000/01/09

[#20237] Ruby/Tk multi interpreter — nagai@...

永井@知能.九工大です.

21 messages 2000/01/17
[#20242] Re: Ruby/Tk multi interpreter — nagai@... 2000/01/17

永井@知能.九工大です.

[#20248] Re: Ruby/Tk multi interpreter — Hideto ISHIBASHI <s34204@...> 2000/01/17

石橋秀仁です。

[#20254] Re: Ruby/Tk multi interpreter — nagai@... 2000/01/18

永井@知能.九工大です.

[#20271] Re: Ruby/Tk multi interpreter — Hideto ISHIBASHI <s34204@...> 2000/01/18

石橋秀仁です。

[#20249] FTP.open err for Windows95 — "Y Kataoka" <kataoka@...>

初めまして、片岡@KLUGと申します。

18 messages 2000/01/17
[#20252] Re: FTP.open err for Windows95 — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/01/18

なひです.

[#20342] How to build ruby(current) with cygwin — KORIYAMA Naohiro <kory@...2.so-net.ne.jp>

はじめまして、こおりやまです。

19 messages 2000/01/23
[#20362] Re: How to build ruby(current) with cygwin — WATANABE Hirofumi <Hirofumi.Watanabe@...> 2000/01/24

わたなべです.

[#20422] Re: How to build ruby(current) with cygwin — Masaki Suketa<CQN02273@...> 2000/01/29

Win32OLE の作者の助田です.

[#20394] ruby-1.4.3 port to HPUX 11.00 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

15 messages 2000/01/26

[ruby-list:20267] Re: non-block IO with TCPSocket

From: Wakou Aoyama <wakou@...>
Date: 2000-01-18 18:29:20 UTC
List: ruby-list #20267
青山です。

On Fri, 7 Jan 2000 12:22:44 +0900,
dn <daisuke@sanpo.t.u-tokyo.ac.jp> wrote:

> loop do
> 	print "."
> 	
> 	activate = select socks,nil,nil,0
> 	
> 	next if activate.nil? 

select() は timeout 時に nil を返しますから、timeout を永遠に待たせれ
ば、決して nil を返す事は無く、このループは不要になります。最後の2行
をまとめて、IO::select(socks) で十分でしょう。(そうならなければ、ruby
のバグという事ですよね?)

> 	if tcpsock.eof?

eof? は、次の1文字が読み込めなかった場合に true になり、それを実際に
読み込んで確認していますが、socket に関しては接続している限りは次の1
文字が読み込める可能性があるので、延々とその時を待ち続ける事になります。

これは max_size または eof まで読み込む read() も同様で、max_size に行
き付けば良いのですが、そうでなければ、延々と待ち続けます。

回避策としては、行指向である場合には、gets() が手軽です。行毎に処理が
帰ってきますし、改行が来ない場合には、延々と待ち続けてくれて良いわけで
すから。

sock = TCPSocket.open("localhost", "echo")
while line = $stdin.gets
  sock.write(line)
  print(sock.gets)
end
sock.close

一方、行指向で無い場合には、eof を待たない、相手からのデータが途切れれ
ば、max_size 以下であろうが、eof でなかろうが、そこまでのデータを返す、
sysread() を使用する事になるでしょう。

sock = TCPSocket.open("0", "echo")

Thread.start do
  loop do
    IO::select([sock])
    begin
      print sock.sysread(4096)
    rescue EOFError  # End of file reached
      break
    end
  end
end

while line = $stdin.gets
  length = line.length
  while 0 < length
    IO::select(nil, [sock])
    length -= sock.syswrite(line[-length..-1])
  end
end
sock.close unless sock.closed?

これは相手が返すデータが不明な場合の例です。何かプロンプトのようなもの
がある場合には Thread は不要で、そのプロンプトまで sysread() のループ
を繰り返せば良いです。

さらに、プロンプトを待ってから次の処理をするような場合には、別 Thread
にしてしまうと同期が必要になるので、むしろ分けない方が簡単です。また、
そのような場合には telnet.rb も便利です。

-----
あ、telnet.rb の write() って、間違っていますね。よく問題が発生しなかっ
たものだ... telnet.rb-1.10.gz を in.coming に入れて置きました。1.4 系
でも動くと思いますので、そちらへもお願いします。(cgi.rb の 1.10 も 1.4
系でも大丈夫と思います。)


-- 
青山 和光 Wakou Aoyama <wakou@fsinet.or.jp>

In This Thread

Prev Next