2016-07-08 4 views
0

Java NIO를 사용하여 Non Blocking Htttp Server를 구현했습니다. x-www-form-urlencoded POST 요청에 대해서는 잘 작동합니다. 하지만 큰 파일로 HTTP 멀티 파트 요청을 시도 할 때 작동하지 않습니다. 이 상황에서 서버는 http 클라이언트에 응답 할 수 없습니다. 이것은 NIO 서버용 소스 코드입니다.Java NIO Httpp 서버에서 멀티 파트 양식 데이터를 처리하는 방법

public class TCPServer { 

    public static void main(String[] args) { 
     TCPServer server = new TCPServer(); 
     server.listen(); 
    } 

    public void listen() { 

     try { 

      Selector selector = Selector.open(); 

      ServerSocketChannel serverSocketChannel = ServerSocketChannel 
       .open(); 

      InetSocketAddress serverAddress = new InetSocketAddress(8080); 

      serverSocketChannel.bind(serverAddress); 

      serverSocketChannel.configureBlocking(false); 

      serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 

      while (true) { 

        selector.select(); 

        Set<SelectionKey> selectionKeys = selector.selectedKeys(); 
        Iterator<SelectionKey> iterator = selectionKeys.iterator(); 

        while (iterator.hasNext()) { 
         SelectionKey key = iterator.next(); 

         if (key.isAcceptable()) { 
          SocketChannel clientSocketChannel = serverSocketChannel.accept(); 

         clientSocketChannel.configureBlocking(false); 

         clientSocketChannel.register(selector, 
          SelectionKey.OP_READ); 

         } else if (key.isReadable()) { 
          SocketChannel clientSocketChannel = null; 
          try { 
           clientSocketChannel = (SocketChannel) key.channel(); 

           ByteBuffer clientBuffer = ByteBuffer.allocate(1024); 

           StringBuilder requestStringBuilder = new StringBuilder(); 

           int bytesRead = clientSocketChannel 
           .read(clientBuffer); 

           while (bytesRead > 0) { 

            clientBuffer.flip(); 

            String result = new String(clientBuffer.array()); 
            requestStringBuilder.append(result); 

            clientBuffer.compact(); 

            bytesRead = clientSocketChannel.read(clientBuffer); 

           } 

           System.out.println("request-----"); 
           System.out 
            .println(requestStringBuilder.toString()); 

           clientSocketChannel.write(ByteBuffer 
            .wrap("reply from server".getBytes())); 

           clientSocketChannel.register(selector, 
           SelectionKey.OP_WRITE); 
        } catch (Exception e) { 
         System.err.println(e.getMessage()); 
         clientSocketChannel.close(); 
        } 

       } else if (key.isWritable()) { 
        SocketChannel clientSocketChannel = null; 
        try { 
         clientSocketChannel = (SocketChannel) key.channel(); 
         clientSocketChannel.close(); 
        } catch (Exception e) { 
         System.err.println(e.getMessage()); 
         clientSocketChannel.close(); 
        } 
       } 
       iterator.remove(); 

      } 
      } 
     }catch (Exception e) { 
      System.err.println(e.getMessage()); 
     } 

    } 

} 

Java NIO 비 차단 서버에서 HTTP 멀티 파트 요청을 처리하는 다른 방법이 있습니까? 어떻게 해결할 수 있습니까? 감사.

+0

'서버가 http 클라이언트에 응답 할 수 없음'은 문제 설명이 아닙니다. – EJP

+0

소스 코드를 사용하여 설명하겠습니다. 서버에 HTTP multipart 요청을 보내는 것으로 가정합니다. 요청에 이미지가 포함되어 있습니다. 구현에 따르면 HTTP 요청이 인쇄 된 다음 서버가 클라이언트에 메시지를 저장합니다. 이 메시지가 클라이언트에 전송되지 않는 문제가 있습니다. 서버에서 처리하는 동안 서버와 클라이언트 간의 연결이 다운 된 것 같습니다. 나는 이유가 무엇인지 모른다. – Tharanga

답변

0

이 질문은 다른 질문과 비슷합니다 : Servlet 3.1 - Multipart async processing하지만 해결책은 일반 논 블로킹 IO에서도 작동하므로 여기에서 대답하겠습니다.

최근 Synchronoss Technologies는 비 블로킹 HTTP 멀티 파트 파서 here을 오픈 소스로 제공했습니다.

비 차단 서버가 데이터를 수신하므로 수신 바이트를 으로 전달하기 만하면됩니다. 파서는받은 각 파트에 대해 코드에 대한 콜백을 수행합니다.

면책 조항 : Synchronoss Technologies에서 근무하고 있습니다. 우리는 Servlet 3.1에 이것을 작성했지만 의도적으로 일반적인 비 차단 애플리케이션에서도 작동해야하므로 다른 사람들이이 라이브러리를 유용하게 사용할 수 있기를 바랍니다.

+0

안녕하세요, 고마워요. 나는 이것이 Servlet과 잘 작동 할 것이라고 생각한다. 하지만이 작업을 위해 Servlet을 사용하지 않습니다. Java NIO를 사용하여 웹 서버를 구현했습니다. Java NIO 웹 서버에서 synchronoss lib를 어떻게 사용할 수 있는지 설명해주십시오. 감사. – Tharanga

+0

이 구문 분석기는 OutputStream처럼 작동합니다. 따라서 도착할 때마다 매번 바이트 수를 쓸 수 있습니다. 한 번에 모든 바이트를 제공 할 필요는 없습니다. 파서는 바이트가 도착하기를 기다리는 동안 스레드를 차단하지 않습니다 (자체 스레드가 없기 때문에). 그러나 바이트를 파싱하는 동안 호출 알고리즘을 사용하여 코드로 콜백을 수행합니다. 또한 서블릿 API에 대한 의존성이 없다는 점에 유의하십시오. 소스가 무엇이든간에 바이트를 제공하는 것은 코드에 달려 있습니다. – npgall

관련 문제