소켓 프로그래밍에서...

kangduel의 이미지

client가 브라우저일 때,
client로부터 요청받은 자료를 서버가 보내주어야하는데...

http같은 경우는 어떤 식으로 서버로 자료를 요청하나요??
예를 들어,
ip와 포트번호로 브라우저에서 html문서를 요청하면 브라우저로 뿌려줘야하는데, 브라우저로부터 받은 ip와 포트번호는 어떻게 서버에서 받아 처리하나요??

감이 잘안오네요...

alsong의 이미지

찾아보니까 HTTP 프로토콜 만만치 않네요 ㅎㅎ 헤더들이 문자열로 이루어 졌군요.
TCP/IP의 상위에서 데이터를 주고 받고...
메시지의 헤더는 4가지 종류가 있네요

 general-header (section 4.5),
 request-header (section 5.3),
 response-header (section 6.2), 
 entity-header (section 7.1) ,
Request의 경우

모두다 전개하지는 않았고요.... 아래와 같은 형식으로 되어 있네요.(아고 힘들러라.

generic-message = start-line
                  *message-header
                  CRLF
                  [ message-body ]

     start-line = Request-Line | Status-Line
	Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
		Method = "OPTIONS"                ; Section 9.2
                         | "GET"                    ; Section 9.3
                         | "HEAD"                   ; Section 9.4
                         | "POST"                   ; Section 9.5
                         | "PUT"                    ; Section 9.6
                         | "DELETE"                 ; Section 9.7
                         | "TRACE"                  ; Section 9.8
                         | extension-method
		SP     = <US-ASCII SP, space (32)>
		Request-URI    = "*" | absoluteURI | abs_path

     message-header = field-name ":" [ field-value ] CRLF
          field-name     = token
          field-value    = *( field-content | LWS )
          field-content  = <the OCTETs making up the field-value
                           and consisting of either *TEXT or combinations
                           of token, tspecials, and quoted-string>

     message-body = entity-body
                   | <entity-body encoded as per Transfer-Encoding>

exam)
GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
xx:xxx(자세히 넣고 싶었지만.... RFC를 잘 찾아보면 나올거예요)
xxxx (여기는 message-body가 들어가겠죠)

서버가 데이터를 받으면...

아주 간단하게 한다면

char ms[10];
char URI[64];
char Version[64];
char buf[2048]
recv(.......) {
   getMethod(ms, buf);
   getURI(URI, buf);
   ....
   if(strcmp(ms, "GET")) {
        proc_get()'
   } else if (strcmp(ms, "HEAD")) {
        proc_head();
   }
}

처리가 되겠지용....
한마디로 대답하기는 힘들고요. 프로토콜의 스펙을 조금은 알고 있어야 합니다.
참고) RFC2068.txt

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

최종호의 이미지

HTTP는 일반적으로 TCP 로 통신을 하고, 기본 포트로는 80번을 사용합니다.

Quote:
HTTP communication usually takes place over TCP/IP connections. The
default port is TCP 80 [19], but other ports can be used. This does
not preclude HTTP from being implemented on top of any other protocol
on the Internet, or on other networks. HTTP only presumes a reliable
transport; any protocol that provides such guarantees can be used;
the mapping of the HTTP/1.1 request and response structures onto the
transport data units of the protocol in question is outside the scope
of this specification.

TCP 는 connecton-oriented 방식이므로, 소켓에 접속이 들어오면 서버에서는 응답할 때 별도로 요청자의 IP와 포트를 지정할 필요가 없습니다. 해당 소켓에 요청한 내용에 대한 응답을 써 주면 클라이언트쪽에 전달됩니다.

간단히 얘기하면 다른 TCP 서버들과 동일하게 동작합니다.

1. 클라이언트에서 서버로 연결요청
                                2. 서버에서 연결수락
(연결됨)
3. 소켓에 원하는 대상 전송요청을 하는 GET명령 보냄
                                4. GET 명령 파싱 후 소켓을 통해 대상전송
(연결종료)
펑키의 이미지

웹서버와의 통신은 기본적으로 TCP/IP 통신입니다. 다른 분들이 올려 주신 글을 자세히 한번 읽어 보세요. 그런데 HTTP/FTP 등의 통신은 먼저 RFC를 다운 받으셔서 가지고 계시는것이 가장 빠른길입니다. 그런 다른에 한가지씩 차근 차근 접근해보세요. 그런후에 HTTP 프로그램들을 소스포지 같은곳에서 다운 받으셔서 한번 비교를 해보세요. 그러면 아 이런곳을 좀더 추가 해야 겠구나 하고 좀더 단단해질겁니다.

1. HTTP 통신에서 자료를 주고 받는 방법은 POST/GET 두가지 방법이 있습니다. 그런데 일반적인 웹서버와의 통신은 POST를 쓰시는 방법이 좋습니다. 크기의 제한이 없거든요. 이것은 실제 HTML 문서가 전송되어야 할 부분에 프로그램 전문을 전송 하는 방법입니다.

2. HTTP 헤더 작성시 유의 하세요. HTTP 통신에서 가장 애를 먹는게 헤더를 작성할때입니다. RFC를 보시고 차근 차근 하나씩 만들어 보시고 다른 웹서버들은 어떻게 응답하는지 한번 TELNET으로 직접 한번 접속해보시면 됩니다.

3. RFC에서 규칙을 보고 따라 하세요. 예를 들면 전송후에 접속을 반드시 끊는다던지 등등...

즐거운 하루 되세요.

송지석의 이미지

음 일단 저도 http 프로그래밍은 잘 모르지만

hedic이란 프로그램이 있습니다. 야후 사전에서 쿼리를 받아오는 프로그램인데요. 지금은 관리가 안되고 있구요. kldp.net에 있습니다.

구조가 간단해서 http 리퀘스트를 어떻게 받아오는지 대충 알겠더군요.

일단 http는 텍스트로 GET , POST 등등으로 시작하는 데이터를 보내면 되더군요. 레퀘스트 끝에는 \n 문자로 줄바꿔주고요.

물론 윗분 말씀대로 확실히 하시려면 스펙을 보셔야 할 겁니다.

int main(int argc, char *argv[])
{
#ifdef WIN32
    WORD wVersionRequired;
    WSADATA wsaData;
    int ErrCode;
#endif
    if (argc < 2)
    {
        printf("Usage : hedic word_to_find\n");
        return -1;
    }
#ifdef WIN32
    wVersionRequired = MAKEWORD(2,0);   //get wsock...
    ErrCode = WSAStartup(wVersionRequired, &wsaData);
    if ( ErrCode !=0)
    {
        printf("WSAStartup error = %d \n", ErrCode);
        return -1;
    }
#endif

    submit(argv[1]);

#ifdef WIN32
    WSACleanup();
#endif
    return 0;
}

이렇게 시작하고요.
submit(argv[1]);
에서 http 리퀘스트를 보내는데
    // 사이트로 찾을 단어를 보냅니다.
    sprintf(buf, "GET %s%s\n", SURL, str);
    send(sd, buf, strlen(buf), 0);

    // 서버에서 출력 해주는 html 문서를 받아 출력합니다.
    parse_result(sd);

SURL은 #define SURL "http://kr.engdic.yahoo.com/result.html?p="
이렇게 정의되어있구요 str은 쿼리할 단어(argv[1])입니다.
onyx의 이미지

RFC를 참고하세요.

영문 -> www.ietf.org
한글 -> http://www.linox.net/Mystuff/HTTP_doc/C11.html

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.