프록시 서버를 구성하고 있는데 궁금한 점이 있습니다.

ansgud21의 이미지

typedef struct {
int connected_sd;
struct sockaddr_in client;
}entity;

// 접속한 클라이언트의 갯수
int clnt_count=0;
// 스레드간 공유변수의 상호배제를 위함
pthread_mutex_t mutex;

static void* proxy_thread(void *arg)
{
int connected_sd; // 새로운 클라이언트와의 연결을 위한 sd
int server_sd;
int n,bytes_to_read;
struct sockaddr_in client;
struct sockaddr_in server;
char *bp;
My_packet packet;

/*****************************************************************
이하 스레드 생성후, 각 데이터 초기화
***************************************************************/
connected_sd = ((entity*)arg)->connected_sd;
memcpy(&client,(struct sockaddr_in*)&(((entity*)arg)->client),sizeof(struct sockaddr_in));
free(arg);

printf("new Client (%s) is connected \n",Sock_ntop((struct\
sockaddr*)&client,sizeof(client)));
pthread_mutex_lock(&mutex);
clnt_count++;
pthread_mutex_unlock(&mutex);

/*****************************************************************
이하 접속해온 클라이언트로부터 메세지 수신
***************************************************************/
/* bp에 buf의 시작 주소를 할당한다 */
bp = (char*)&packet;
bytes_to_read = sizeof(My_packet);
/* 연결된 클라이언트로 부터 데이터를 수신받는다 */
while((n = read(connected_sd, bp,bytes_to_read))>0){
bp += n;
bytes_to_read -= n;
}

/*****************************************************************
메세지를 수신받은후.. 클라이언트가 접속하길 희망하는
서버로 연결 시도
***************************************************************/
/* AF_INET 스트림 소켓을 생성한다 */
server_sd = Socket(AF_INET,SOCK_STREAM,0);

/* sockaddr_in 구조체를 0으로 초기화 시킨다. */
bzero((char*)&server,sizeof(struct sockaddr_in));
bcopy(&(packet.server.sin_family),&(server.sin_family),sizeof(server.sin_family));
bcopy(&(packet.server.sin_port),&(server.sin_port),sizeof(server.sin_port));
bcopy(&(packet.server.sin_addr),&(server.sin_addr),sizeof(server.sin_addr));

printf("before connect\n");
Connect(server_sd,(struct sockaddr*)&server,sizeof(struct sockaddr_in));
printf("Connected : server's IP address is %d\n",server.sin_addr);
printf("after connect\n");

write(server_sd,packet.buf,BUFLEN);
printf("%s\n",packet.buf);

/* empty message일 경우 연결을 종료한다 */
/*
if(!strcmp(buf,"")){
close(connected_sd);
printf("Client (%s) is disconnected \n",Sock_ntop((struct\
sockaddr*)&client,sizeof(client)));
pthread_mutex_lock(&mutex);
clnt_count--;
pthread_mutex_unlock(&mutex);
return;
}
printf("%s > %s\n",Sock_ntop((struct sockaddr*)&client,sizeof(client)),buf);

*/
/* 클라이언트로 부터 수신된 메세지를 다시 클라이언트에 echo */
/*
write(connected_sd,buf,BUFLEN);
printf("%s(echo) > %s\n",Sock_ntop((struct sockaddr*)&client,sizeof(client)),buf);
*/
return 0;
}

int main(void)
{
pthread_t tid;
entity *client_entity = NULL;
int sd,new_sd;
socklen_t client_len;
struct sockaddr_in proxy;
struct sockaddr_in client;

//port = SERVER_TCP_PORT;

// 소켓의 프로토콜 타입을 지정한다.
if((sd = socket(AF_INET, SOCK_STREAM,0)) == -1){
fprintf(stderr,"Cant Create a socket\n");
exit(1);
}

// sockaddr_in proxy 구조체를 0으로 초기화한다
bzero((char*)&proxy, sizeof(struct sockaddr_in));
proxy.sin_family = AF_INET; // IPv4
// 포트 번호에 대해서,
// 호스트 바이트 순서를 네트워크 바이트 순서로 변환한다
proxy.sin_port = htons(PROXY_TCP_PORT);
// IP 주소에 대해서,
// 호스트 바이트 순서를 네트워크 바이트 순서로 변환한다
proxy.sin_addr.s_addr = htonl(INADDR_ANY);
/* 소켓에 로컬 프로토콜 주소를 바인드한다 */
Bind(sd,(struct sockaddr*)&proxy, sizeof(proxy));

/* linten() 함수는 소켓을 CLOSED 상태에서 LISTEN 상태로 변화시킨다*/
listen(sd,5);

client_len = sizeof(client);

/* three-way handshake가 완료되었을때 Acceept함수는 리턴되며,
이 함수의 리턴값은 연결된 새로운 소켓의 디스크립터이다 */

while(1){
/* 클라이언트 접속 대기 */
new_sd = Accept(sd,(struct sockaddr *)&client,&client_len);

/* 이하 구조체 초기화 */
client_entity = (entity*)calloc(1,sizeof(entity));
((entity*)client_entity)->connected_sd = new_sd;
memcpy(&(((entity*)client_entity)->client),&client,sizeof(struct sockaddr_in));
/* 쓰레드 생성 */
pthread_create(&tid,NULL,&proxy_thread,client_entity);
}
/* close listening socket */
close(sd);
return 0;
}

이게 에코프록시 서버 코드구요..
여기서 좀 더 발전시켜서 실제로 구글 같은 웹서버랑 연결하는 프록시 서버로 만들려고 하는데요.
어떻게 발전시켜야 하는지 잘 모르겠는데, 조언 좀 주실수 있으신가요?

mithrandir의 이미지

코드를 본문에 포함하실때는 코드블럭을 사용해주세요;;

코드를 읽어보진 않았지만, 우선 구현하시려는 기능을 생각해보시고,
로직을 정리하신 후에, 기능에 필요한 코드 예제를 찾아보시기 바랍니다.

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

댓글 달기

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