2013-10-29 73 views
0

我正在用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?這是做這件事的正確方法嗎?

+0

這看起來像是一個多線程問題。你能擴展你的簡化初始代碼嗎?好像你在同一個流上同時調用'read'和'write'。 InputStream/OutputStream只能使用一種方法,並調用讀/寫方法來提升它們。這就是爲什麼你得到無效的讀/寫,因爲這兩個線程同時讀/寫並獲取不完整的數據。與沒有EOF相同,如果輸出流正在寫入到您正在讀取的同一個地方,您將得到一個無盡的IO循環。 – Radiodef

+0

從服務器讀取的線程是否讀取了-1? – Joni

+0

@Joni:是的。 –

回答

0

「我認爲這是因爲我的HTTP請求有Connection:keep-alive,我該如何處理? 我想也許你可以打開你的套接字一次連接。 嘗試擁有isNewConnection之類的標誌。首先將其設置爲true,並在連接啓動後將其設置爲false。