Java로 HTTP 통신을 할때..

litnsio2의 이미지

학교과제로 간단한 HTTP 서버를 작성하고 있습니다.
요구된 기능은

클라이언트 C가 제가 작성한 서버 S 의 특정 페이지를 열면
간단한 폼이 있는데 그 폼에 D의 url 을 입력하면
서버 S가 D의 문서를 받아 C에게 중계해주는 것입니다.
(즉, S 에는 아주 간단한 CGI 기능도 있다는 이야기입니다)

문제는 HTTP를 이용하여 D의 문서를 가져오는 일인데
(HTTPConnection 클래스가 아닌 일반 소켓을 이용하여 작성하고 있습니다)
HTTP 리퀘스트를 보내는데는 문제가 없는데 받는데 문제가 생기는군요.
1k 미만의 작은 문서는 수월하게 가져오는데에 비해,
daum.net 의 루트와 같은 커다란 문서를 제대로 받지 못하는것 같네요..;;

아무래도 문서 자체가 커서 여러개로 쪼개져서 보내지는 것일텐데
(패킷 캡춰를 해보면 1400씩 오더군요.. 물론 이건 IP 레이어에서 본거고
그 위에서 S가 읽어오는 데이터양은 매번 다르겠죠)
S가 첫번째 패킷만 받고 나머지 패킷은 받지를 못합니다...=ㅁ=

코드를 간단히 보면..

    private void receive() throws Exception {
        int nSizeRead = 0;
        byte buffer[] = new byte[400];
        while( true ) {
            log("데이터 수신중..");
            nSizeRead = _dataInputStream.read(buffer);
            log(new String(buffer));

            log("읽은 사이즈 : " + nSizeRead);

             if( nSizeRead == -1 )
                break;
        }
    }

(참고로 receive() 메서드는 run()에서 호출된 메서드입니다)
첫번째 패킷은 제대로 받는데.. 두번째 패킷부터는.. 제대로 받을때도
있고 그렇지 못할 때도 있습니다.
(어떤 경우에는 같은 데이터를 두번 받기도..=ㅁ=)
제가 HTTP 에 대해서 제대로 알지 못하고 프로그래밍을 해서 그런지
문제가 많네요..

일단 저 부분만 해결이 되면 나머지는 문제가 없을 터인데..
저 코드에서 문제점이 어디에 있는지 가르침 부탁드리옵니다...

ps. 패킷 캡춰를 해보니까.. HTTP 패킷 하나를 받은 후에
S가 D한테 ZeroWindow 를 보내네요.. 버퍼(여유윈도우)가
없다는 소리인데.. 음...
대체 뭐가 문제인지...-_- 혹시나 해서 TCP ZeroWindow 패킷을...;;

Quote:

TCP: [TCP ZeroWindow][TCP Dup ACK 14*1] 2013 > http [RST, ACK] Seq=37 Ack=369 Win=0 Len=0
litdream의 이미지

기본적인 URL 의 기능입니다.
java.net.URL 을 한번 보세요. 도움 되실거구요.
java tutorial 에서 Custom Networking trail 을 읽어보시면 사용법 나옵니다.
도움 되셨길..

삽질의 대마왕...

monac의 이미지

기존 java 클래스를 안쓰는 데에는 사정이 있겠지요.

데이터를 받지 못한다고 하시는데 어떻게 못받는다는 것인지 모르겠습니다. read()에서 그냥 blocking 되어서 멈춰서 있는 것인가요? 아님 조금만 받고 연결이 끊어지나요?

혹시 에러 문서 (200 OK 가 아닌 다른 에러값) 가 넘어오는거 아닌가요? http protocol 의 에러 처리를 하셨는지 모르겠습니다.

litnsio2의 이미지

monac wrote:

데이터를 받지 못한다고 하시는데 어떻게 못받는다는 것인지 모르겠습니다. read()에서 그냥 blocking 되어서 멈춰서 있는 것인가요? 아님 조금만 받고 연결이 끊어지나요?

패킷캡춰를 해보면
HTTP Continuation 으로 오고요..
문제는 저 코드에서 첫번째 루프에서는 이녀석이 데이터를 받는데
(약 4~500 바이트정도)
두번째 루프에서는 데이터를 못받는다는 이야기입니다..
두번째 루프에서 read() 에서 블록이 되다가 timeout 이 나면
-1 을 리턴하고 루프가 종료됩니다..

으으.. 꼭 URL 클래스를 써야하는건지.. ㅡㅜ

cjh의 이미지

--
익스펙토 페트로눔

litnsio2의 이미지

litnsio2 wrote:
monac wrote:

데이터를 받지 못한다고 하시는데 어떻게 못받는다는 것인지 모르겠습니다. read()에서 그냥 blocking 되어서 멈춰서 있는 것인가요? 아님 조금만 받고 연결이 끊어지나요?

패킷캡춰를 해보면
HTTP Continuation 으로 오고요..
문제는 저 코드에서 첫번째 루프에서는 이녀석이 데이터를 받는데
(약 4~500 바이트정도)
두번째 루프에서는 데이터를 못받는다는 이야기입니다..
두번째 루프에서 read() 에서 블록이 되다가 timeout 이 나면
-1 을 리턴하고 루프가 종료됩니다..

으으.. 꼭 URL 클래스를 써야하는건지.. ㅡㅜ

URL 클래스써도.. 결과는 마찬가지.. 역시나 HTTP 에 대한 이해가 부족해서인듯..;;

matrix의 이미지

URL클래스도 socket을 이용하기때문에 똑 같을겁니다.

receive 메소드의 내용을 run 에 넣어서 수행하세요.

run()을 실행하는 Thread와 receive()를 실행하는 Thread가 동일하다는 보장이 없습니다.

반드시 run() 메소드에서 패킷을 처리하세요.

소스자체는 문제가 없습니다.

How do you define Real?

litnsio2의 이미지

matrix wrote:
URL클래스도 socket을 이용하기때문에 똑 같을겁니다.

receive 메소드의 내용을 run 에 넣어서 수행하세요.

run()을 실행하는 Thread와 receive()를 실행하는 Thread가 동일하다는 보장이 없습니다.

반드시 run() 메소드에서 패킷을 처리하세요.

소스자체는 문제가 없습니다.

감사합니다

정말 패킷처리를 run() 에서 해주니까 잘 되네요. 그런데

Quote:

run()을 실행하는 Thread와 receive()를 실행하는 Thread가 동일하다는 보장이 없습니다.

이부분이 이해가 잘 되질 않습니다. 분명히 맞는 말인것 같기는 한데..
VM 레벨에서 무언가 일이 일어나기 때문인것 같기는 한데...
간단한 설명이나 관련자료가 있으시면.. 좀... ㅠㅠ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.