Re: [問題] Java I/O的問題

看板java作者 (十年~)時間11年前 (2013/05/31 22:50), 編輯推噓3(304)
留言7則, 4人參與, 最新討論串5/5 (看更多)
※ 引述《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

05/31 23:03, , 1F
ohoh 原來如此 !
05/31 23:03, 1F

05/31 23:14, , 2F
其實eof/stream closed不等同正是我想提到的 一兩年前拿
05/31 23:14, 2F

05/31 23:16, , 3F
過這種FIO的特例sdk才知道有這回事 不過你說得清楚多了
05/31 23:16, 3F

05/31 23:17, , 4F
很推薦這篇,講得非常清楚
05/31 23:17, 4F

06/01 20:06, , 5F
nice
06/01 20:06, 5F

06/03 09:58, , 6F
突然想到tomcat6重復使用request-thread造成的問題
06/03 09:58, 6F

06/03 15:17, , 7F
tomcat6重覆使用thread結果造成threadlocal發生問題 XD
06/03 15:17, 7F
文章代碼(AID): #1HgBYYkW (java)
文章代碼(AID): #1HgBYYkW (java)