我正在用Java寫一個代理服務器。input.read()永不返回-1
最初,我(簡化的)
server = new ServerSocket(5568);
incoming = server.accept();
input = incoming.getInputStream();
...
outgoing = new Socket(host, 80);
output = outgoing.getOutputStream();
output.write(inputbuffer, 0, i);
其中INPUTBUFFER是字節的一些集接收爲止(I讀取傳入的數據,直到在那裏我知道主機頭的一部分,然後打開一個連接到服務器併發送我迄今爲止)。所以服務器是我的歡迎套接字,輸入是從客戶端發送到我的代理的數據,輸出是從我的代理服務器發送的數據。
接下來,我希望將服務器的輸出寫入客戶端,並與客戶端並行寫入服務器。所以,我創建一個單獨的線程從客戶端讀取:
final InputStream finalInput = input;
final OutputStream finalOutput = output;
Thread sendingStuff = new Thread(){
public void run(){
int c;
while ((c = finalInput.read()) != -1){
finalOutput.write((byte)c);
finalOutput.flush();
}
finalInput.close();
finalOutput.close();
}
}
sendingStuff.start();
最後,我在主線程中不同的部分從服務器讀取和寫入到客戶端。
InputStream reverseInput = outgoing.getInputStream();
OutputStream reverseOutput = incoming.getOutputStream();
int c;
while ((c = reverseInput.read()) != -1){
reverseOutput.write((byte)c);
reverseOutput.flush();
}
reverseInput.close();
reverseOutput.close();
會發生什麼事是我得到的輸入和輸出發送,但是瀏覽器永遠旋轉,並在從客戶端讀取線程行從來沒有得到一個-1信號。
很多時候我得到的錯誤說「無效的標題名稱」或「您的瀏覽器發送請求,服務器無法理解」,我認爲這與我遇到的這個問題有關。有一次,我甚至在從客戶端讀取的行上發生IOException:Socket關閉。
那麼爲什麼客戶端不發送EOF?這是做這件事的正確方法嗎?
這看起來像是一個多線程問題。你能擴展你的簡化初始代碼嗎?好像你在同一個流上同時調用'read'和'write'。 InputStream/OutputStream只能使用一種方法,並調用讀/寫方法來提升它們。這就是爲什麼你得到無效的讀/寫,因爲這兩個線程同時讀/寫並獲取不完整的數據。與沒有EOF相同,如果輸出流正在寫入到您正在讀取的同一個地方,您將得到一個無盡的IO循環。 – Radiodef
從服務器讀取的線程是否讀取了-1? – Joni
@Joni:是的。 –