[완료] HTTP Relay 또는 Redirect 서버를 만들고 싶습니다.

ljs0766의 이미지

제가 원하는 프로그램은

A,B,C 세 시스템이 존재할 때

A에서 C로는 통신이 되질 않습니다.
A와 B는 통신이 가능하며 B와 C역시 통신이 가능합니다.

따라서 A에서 웹브라우져를 뛰우고
B의 IP주소가 1.1.1.1이라 했을 때
1.1.1.1:5555로 접속을 하면
B에 떠있는 프로세스가 접속을 받아들이고 들어온 HTTP 리퀘스트를
C의 80포트로 다시 날려주는 방식입니다.
그럼 C에서는 다시 HTTP 리스폰스를 B로 던져주고 B는 이를 다시 A에게 전달하여
A에서 C의 웹페이지가 보이게 하는 프로그램입니다.

현재 대부분의 구현이 끝났는데 한가지 문제가 발생했습니다.
C에서 서비스중인 웹사이트가 이미지와 플래쉬로 도배가 된 사이트인데
제가 작성한 루틴으로는 이미지를 제대로 보여주지 않는군요...
이미지가 2~3개뿐인 간단한 텍스트 기반 페이지는 잘보여주는데 이미지가 좀 많아지거나 하면
-ㅁ-; 굉장히 아스트랄한 화면을 보여줍니다.
우선 코드 세그먼트 올립니다. ^^

아래 부분은 접속한 클라이언트로 부터 HTTP 리퀘스트를 받아서 그대로 서버에게 전달하는 부분입니다.

for( i = 0 ; i < MAX_CONN ; i++ ) {
            if( _stServerInst.nConnSock[i] > 0 && FD_ISSET( _stServerInst.nConnSock[ i ] , &fdIn ) ) {
 
                do {
                    memset( _stServerInst.szMsgBuf , 0 , sizeof( char ) * MSGBUF_SIZE );
                    memset( szMsgBuf , 0 , sizeof( char ) * MSGBUF_SIZE );
 
                    nRead   =   _stServerInst.ReadMessage( _stServerInst.nConnSock[ i ] , _stServerInst.szMsgBuf );
 
                    if( nRead <= 0 ) {
                        close( _stServerInst.nConnSock[ i ] );
                        _stServerInst.nConnSock[ i ]    =   -1;
                        continue;
                    }
 
                    memcpy( szMsgBuf , _stServerInst.szMsgBuf , sizeof( char ) * nRead );
 
                    nWrite  =   _stServerInst.WriteMessage( _stServerInst.nCliSock , _stServerInst.szMsgBuf , nRead );
 
                    if( nWrite <= 0 ) {
                        close( _stServerInst.nCliSock );
                        _stServerInst.OpenClient();
                        continue;
                    }
                } while( nRead >= MSGBUF_SIZE );
            }
        }

이 부분은 서버로부터 HTTP Response를 받아서 클라이언트에게 그대로 던지는 부분이고요

if( _stServerInst.nCliSock > 0 && FD_ISSET( _stServerInst.nCliSock , &fdIn ) ) {
            nRead   =   MSGBUF_SIZE;
 
            do {
                memset( _stServerInst.szMsgBuf , 0 , sizeof( char ) * MSGBUF_SIZE );
                memset( szMsgBuf , 0 , sizeof( char ) * MSGBUF_SIZE );
 
                nRead       =   _stServerInst.ReadMessage( _stServerInst.nCliSock , _stServerInst.szMsgBuf );
 
                if( nRead <= 0 ) {
                    close( _stServerInst.nCliSock );
                    _stServerInst.OpenClient();
                    continue;
                }
 
                fprintf( stdout , "%dbytes received.\n" , nRead );
                fprintf( stdout , "%s\n" , _stServerInst.szMsgBuf );
 
                memcpy( szMsgBuf , _stServerInst.szMsgBuf , sizeof( char ) * nRead );
 
                for( i = 0 ; i < MAX_CONN ; i++ ) {
                    if( _stServerInst.nConnSock[ i ] > 0 ) {
                        nWrite  =   _stServerInst.WriteMessage( _stServerInst.nConnSock[ i ] , szMsgBuf , nRead );
 
                        if( nWrite <= 0 ) {
                            close( _stServerInst.nConnSock[ i ] );
                            _stServerInst.nConnSock[ i ]    =   -1;
                        }
                    }
                }
            } while( nRead >= MSGBUF_SIZE );
        }

뭐가 잘못됬는지 궁금합니다. ^^;;

로그를 찍어보니 한꺼번에 이미지를 못받아오고 하나하나씩 차례차례 받아오는 모습을 볼 수 있었는데
그것과 관계가 있는 것일 까요???

atomaths의 이미지

원하시는 B의 역할을 apache의 proxy balancer가 해주는 것으로 알고 있는데요.
B가 단지 그 역할만 하는 것이 아니라면 소용이 없을지도 모르겠습니다.

ljs0766의 이미지

지금 상황이 apache를 사용하지 못하고 B의 역할을 수행하는 단일 프로세스만을 뛰워야 해서요 ^^
apache사용할 수 있으면 고민같은거 하지 않겠죠 ^^;;;
그리고 B 프로세스에 다른 기능들도 추가될 예정이라...저렇게 해야만 하는 상황이 와버렸습니다 ㅠ.ㅠ

7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

버퍼 크기가 작아서 그런 것 아닐까요?

무한포옹의 이미지

socat 을 참조해 보세요.
-------------------------------
인생 뭐 있음!

-------------------------------
== warning 대부분 틀린 얘기입니다 warning ===

ljs0766의 이미지

제가 잠시 HTTP의 기본적인 동작에 대해서 깜박하고 있었네요...
웹페이지 받아올 때 하나하나의 Object에 대해서 Request를 날리고 Response를 받는 사실을 깜박했네요.
브라우져에서 제 프로세스에 connect할 때마다 fork해서 처리하는 방식으로 일단 해결봤습니다.
fork한 프로세스는 지정된 시간동안 아무런 request가 없고 response가 없으면 알아서 죽도록 했더니 문제없이 작동하는 군요
크게 퍼포먼스가 필요없는 부분이라 이정도만 해도 될듯 하네요 ^^

댓글 달기

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