2010-03-03 9 views
0

현재 브라우저에서 HTTP 요청을 받고 처리 한 다음 원하는 웹 서버로 전달하는 간단한 프록시 서버에서 작업하고 있습니다.자바 소켓 프로그래밍 - 스트림이 막히게

브라우저에서 연결된 소켓의 입력 스트림에서 요청을 가져 오려고 시도하지만 데이터의 마지막 블록을받은 후에 스트림이 멈추는 것을 제외하고는 모든 것이 좋습니다.

ServerSocket servSocket = new ServerSocket(8282); 
Socket workSocket = servSocket.accept(); 
InputStream inStream = workSocket.getInputStream(); 
byte[] buffer = new byte[1024]; 
int numberRead = 0; 

while ((numberRead = inStream.read(buffer, 0, 1024)) != -1){ 
System.out.println(new String(buffer)); 
} 

루프는 단순히 종료 할 수없는, 심지어 요청 수신이 완료되면 아래 그림과 같이

내 코드는 사실 매우 간단합니다.

이 문제를 해결할 수있는 방법이 있습니까?

미리 조언 해 주셔서 감사합니다.

+0

우리는 문제를 찾기 위해 세부 정보를 제공하고 소스 코드를 제공해야합니다. –

+0

코드가 추가되었습니다. 조언 해주세요. –

+0

왜 아파치 HTTPD와 mod_proxy를 설치하지 않는가? – pjp

답변

0

연결이 닫히고 클라이언트가 HTTP 응답을 기다리고 있고 닫지 않을 때까지 반복됩니다.

+0

이 경우 스레드를 사용하는 것 외에 요청을 처리 할 방법이없는 것 같습니다. –

+0

음, 선택 및 비 차단 읽기/쓰기를 사용할 수 있습니다.이 경우 한 스레드 만 수행 할 수 있습니다. 나는 Java 전문가는 아니지만 자세한 내용을 알려줄 수는 없습니다. –

1

InputStream javadoc에서와 같이이 메서드는 데이터를 사용할 수 있거나 EOF가 발생할 때까지 차단됩니다. 따라서 Socket의 다른 쪽이이를 닫아야합니다. 그러면 inStream.read() 호출이 반환됩니다.

또 다른 방법은 먼저 읽으려는 메시지의 크기를 보내는 것입니다. 그러면 미리 읽어야하는 바이트 수를 알 수 있습니다. 또는 BufferedReader를 사용하여 소켓에서 줄 단위로 읽을 수 있습니다. BufferedReader에는 라인을 읽을 때마다 반환하는 readLine() 메서드가 있습니다. 이는 HTTP 프로토콜 패키지가 선으로 나뉘어져있어 잘 작동합니다.

+0

그러나 소켓에 연결하는 클라이언트는 firefox 또는 IE와 같은 브라우저입니다. 브라우저를 제어 할 방법이 없으며 처음에는 소켓을 닫거나 메시지 크기를 보내지 않습니다. –

+0

그래, BufferedReader를 사용하는 것이 좋습니다.모든 HTTP 패킷은 줄 바꿈되어 있으므로 두 줄을 읽고 이것이 모두 패킷인지 여부를 알 수 있습니다 (항상 줄 바꿈으로 끝납니다). – pajton

+0

BufferedReader 접근 방식을 시도했지만 스트림이 여전히 고정되어 있습니다. –

0

브라우저가 연결을 종료하기 전에 응답을 기다리고 있습니다. 읽기/쓰기가 스트림/연결이 닫히거나 새 데이터가 수신 될 때까지 차단됩니다.

0

현재 코드에 따른 직접적인 해결책은 아닙니다.

HTTP는 라인 기반 프로토콜이므로 Buffered Reader을 사용하고 readLine()을 호출 할 수 있습니다.

+0

BufferedReader 접근 방식을 시도했지만 스트림이 여전히 고정되어 있습니다. –

0

다음은 HTTP 요청이 오면에서 그 것이다 항상 예를 들어, 빈 줄을 체결 : 다음 서버의 응답 전을 기다리는 그 요청을 클라이언트 연결을 보낸 후

GET /someFile.html HTTP/1.1 
Host: www.asdf.com 

연결을 닫습니다. 따라서 사용자의 요청을 구문 분석하려면 빈 줄 텍스트 줄에 도달 할 때까지 BufferedReader를 사용하고 전체 줄을 읽는 것이 좋습니다.