作者sbrhsieh (十年~)
看板java
标题Re: [问题] Java I/O的问题
时间Fri May 31 22:50:06 2013
※ 引述《Killercat (杀人猫™)》之铭言:
: 这个有一个小例外,不过因为太常碰到了,所以回文讲一下
: 我们有时候会有些需求,要用socket对HTTP做手脚,发request/收recv
: HTTP1.0的时候,server传完[header]\r\n\r\n[body]就会很乖的把它断开
: (这个上面看不懂的其实下面也不太需要浪费时间看了,因为这代表没碰过这需求
: 等到实际碰到再回来看就可以了)
: 所以socket.getInputStream()会很乖的如上面所说的断开
: 当然,HTTP版本是可以从request的header去指定的
: HTTP1.1的时候情况就不一样了,除了比以前1.0多要求了一个Host header以外,
: 还多增加了一个叫做Connection的Header。这个Connection header很妙
: 他预设是keep-alive
: Connection: keep-alive
: 这个keep-alive会keep住这个session让他不会断开,即使资料传完了也一样
: 按标准的话印象中是要20秒没资料来回才会断开,那这个socket.getInputStream()
: 问题就很大了...因为他不会自己断,你也不该自己断,这单单用socket其实颇难处理的
: 如果要让他能像以前的行为一样断开的话,你必须把Connection指定为closed
: Connection: closed
: 为什麽预设是keep-alive以及为什麽要支援keep-alive这个就不在本文讨论范围之内了,
: 总之在某些情况下Socket.getInputStream()的确在读完了并不会断开
: 可是,这篇不是讲FileInputStream吗?
: 这就是重点了,FileInputStream的spec中并没有eof会断开的规定,任何设备商
: 要是以pipe来传递,而且overload FileInputStream的话,其实是有绝对的能力
: 去让他read卡在那里读不到东西却不直接执行断开的,而且这种东西实作上是很
: 有可能发生的,端看厂商怎麽实作。
我觉得这一篇提到“特列”似乎与原本讨论的主题没有直接的关联,
而基本上 EOF 与 stream 断掉是不同的一件事。
EOF 是表示再也没有更多的 data,到达 EOF 不代表 stream close,尽管 Java
OutputStream 没有定义送出 EOF 的操作,目前只能以 close stream 的方式去
达到通知接收端 EOF 的作用,但是考虑到 stream 的另一端可以是任意的
软体与设备,我觉得还是要把 EOF 与 stream closed 当做两个不同的概念。
文中提到的 HTTP request 的 Connection: Keep-Alive header 是为了让 client
可以重复利用一个 socket connection 送出多个 HTTP request 给 server,所以
server 当然不能吐完 response body 後就 close stream/connection。
通常会懂得使用 persistent connection 的人一定会知道要从 response header:
Content-Length 来判断 server 送出来的 body 长度(即使不使用 persistent
connection 有时也会去看看 Content-Length),不会只依赖 stream EOF。
至於最後提到 read 卡住,没有 EOF 也没有断掉 stream,有些是没办法确认
end of stream 这件事成立,例如透过硬体上的实体连接线与外部交换资料(
Serial port 等等),而不是没有实做好。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 1.172.241.69
1F:推 cuteclare:ohoh 原来如此 ! 05/31 23:03
2F:推 Killercat:其实eof/stream closed不等同正是我想提到的 一两年前拿 05/31 23:14
3F:→ Killercat:过这种FIO的特例sdk才知道有这回事 不过你说得清楚多了 05/31 23:16
4F:→ Killercat:很推荐这篇,讲得非常清楚 05/31 23:17
5F:推 gmoz:nice 06/01 20:06
6F:→ swpoker:突然想到tomcat6重复使用request-thread造成的问题 06/03 09:58
7F:→ swpoker:tomcat6重覆使用thread结果造成threadlocal发生问题 XD 06/03 15:17