<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=%EC%9D%B4%EC%98%81%ED%98%B8%2F%ED%94%84%EB%A1%9D%EC%8B%9C%EC%84%9C%EB%B2%84%EA%B5%AC%ED%98%84</id>
	<title>이영호/프록시서버구현 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=%EC%9D%B4%EC%98%81%ED%98%B8%2F%ED%94%84%EB%A1%9D%EC%8B%9C%EC%84%9C%EB%B2%84%EA%B5%AC%ED%98%84"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=%EC%9D%B4%EC%98%81%ED%98%B8/%ED%94%84%EB%A1%9D%EC%8B%9C%EC%84%9C%EB%B2%84%EA%B5%AC%ED%98%84&amp;action=history"/>
	<updated>2026-05-16T23:20:26Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://mediawiki.zeropage.org/index.php?title=%EC%9D%B4%EC%98%81%ED%98%B8/%ED%94%84%EB%A1%9D%EC%8B%9C%EC%84%9C%EB%B2%84%EA%B5%AC%ED%98%84&amp;diff=66663&amp;oldid=prev</id>
		<title>imported&gt;Unknown at 05:30, 7 February 2021</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=%EC%9D%B4%EC%98%81%ED%98%B8/%ED%94%84%EB%A1%9D%EC%8B%9C%EC%84%9C%EB%B2%84%EA%B5%AC%ED%98%84&amp;diff=66663&amp;oldid=prev"/>
		<updated>2021-02-07T05:30:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;SPEC&lt;br /&gt;
OS: Linux&lt;br /&gt;
COMPILER: GCC&lt;br /&gt;
(잡았음) 처음 접속은 성공적이나 두번째 접속부터 target_sock의 할당이 제대로 이루어지지 않고 있음. 이 버그를 잡아야함.&lt;br /&gt;
(Not Yet) target() 함수가 종료되지 않음. recv()를 Non-Blocking으로 할당하고 Message가 오지 않으면 target() 함수를 종료시키는 방법을 써야겠음.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
fork()로 child process 생성 후, parent process를 제거.&lt;br /&gt;
child process에서 setsid()로 session leader권한 부여.&lt;br /&gt;
child process는 thread를 사용하여 동기화함.&lt;br /&gt;
child process는 daemon process로 background에서 실행됨.&lt;br /&gt;
&lt;br /&gt;
www protocol도 사용 가능하지만 www protocol로 제작된 것이 아니여서 하나의 사이트만 접속 가능.&lt;br /&gt;
irc proxy 제작을 목표로 완성 되었음.&lt;br /&gt;
// www protocol을 구현하려면 thread 시작 부분에서 connect 부분을 고쳐야함.&lt;br /&gt;
// 물론 www protocol의 RFC 문서를 참고하여 패킷 교환 방식을 제작해야함.&lt;br /&gt;
&lt;br /&gt;
Test Page : http://zeropage.org:8088&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // pthread 라이브러리를 링크시 첨가해야함.&lt;br /&gt;
 // gcc source.c -lpthread&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;amp;lt;stdio.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;stdlib.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;string.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;sys/types.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;sys/socket.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;arpa/inet.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;netdb.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;unistd.h&amp;amp;gt;&lt;br /&gt;
 #include &amp;amp;lt;pthread.h&amp;amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #if !defined(TRUE)&lt;br /&gt;
 #define TRUE 1&lt;br /&gt;
 #endif&lt;br /&gt;
 #define MSG_MAX 1024&lt;br /&gt;
 #if !defined(_REENTRANT)&lt;br /&gt;
 #define _REENTRANT&lt;br /&gt;
 #endif&lt;br /&gt;
 &lt;br /&gt;
 void *target(void *arg);&lt;br /&gt;
 void *client(void *arg);&lt;br /&gt;
 &lt;br /&gt;
 pthread_mutex_t mutex;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
                 int server_sock;&lt;br /&gt;
                 int client_sock;&lt;br /&gt;
                 int target_sock;&lt;br /&gt;
                 struct sockaddr_in server_addr;&lt;br /&gt;
                 struct sockaddr_in client_addr;&lt;br /&gt;
                 struct sockaddr_in target_addr;&lt;br /&gt;
                 struct hostent *h = NULL;&lt;br /&gt;
                 int client_addr_size;&lt;br /&gt;
                 int option = TRUE;&lt;br /&gt;
                 pid_t pid;&lt;br /&gt;
                 pthread_t tid;&lt;br /&gt;
                 int sock[2];&lt;br /&gt;
 &lt;br /&gt;
                 if(argc != 4)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;Usage: %s &amp;amp;lt;Target-Host&amp;amp;gt; &amp;amp;lt;Target-Port&amp;amp;gt; &amp;amp;lt;Port&amp;amp;gt;\n&amp;quot;, argv[0]), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                 h = gethostbyname(argv[1]);&lt;br /&gt;
                 if(h == NULL)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;gethostbyname() error: %s\n&amp;quot;, argv[1]), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                 server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);&lt;br /&gt;
                 if(server_sock == -1)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;socket() error: server_sock(%d)\n&amp;quot;, server_sock), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                 memset(&amp;amp;amp;server_addr, 0, sizeof(server_addr));&lt;br /&gt;
                 server_addr.sin_family = AF_INET;&lt;br /&gt;
                 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
                 server_addr.sin_port = htons(atoi(argv[3]));&lt;br /&gt;
 &lt;br /&gt;
                 memset(&amp;amp;amp;target_addr, 0, sizeof(target_addr));&lt;br /&gt;
                 target_addr.sin_family = AF_INET;&lt;br /&gt;
                 target_addr.sin_addr = *(struct in_addr *)h-&amp;amp;gt;h_addr_list[0];&lt;br /&gt;
                 target_addr.sin_port = htons(atoi(argv[2]));&lt;br /&gt;
 &lt;br /&gt;
                 if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &amp;amp;amp;option, sizeof(option)) == -1)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;setsockopt() error: server_sock(%d)\n&amp;quot;, server_sock), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                 if(bind(server_sock, (struct sockaddr *)&amp;amp;amp;server_addr, sizeof(server_addr)) == -1)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;bind() error: server_sock(%d)\n&amp;quot;, server_sock), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                 if(listen(server_sock, 1) == -1)&lt;br /&gt;
                                 fprintf(stderr, &amp;quot;listen() error: server_sock(%d)\n&amp;quot;, server_sock), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                 pthread_mutex_init(&amp;amp;amp;mutex, NULL);&lt;br /&gt;
 &lt;br /&gt;
                 pid = fork();&lt;br /&gt;
                 switch(pid)&lt;br /&gt;
                 {&lt;br /&gt;
                                 case -1:&lt;br /&gt;
                                                 fprintf(stderr, &amp;quot;fork() error: pid(%d)\n&amp;quot;, pid), exit(-1);&lt;br /&gt;
                                 case 0:&lt;br /&gt;
                                                 while(1){&lt;br /&gt;
                                                                 client_sock = accept(server_sock, (struct sockaddr *)&amp;amp;amp;client_addr, &amp;amp;amp;client_addr_size);&lt;br /&gt;
                                                                 if(client_sock == -1)&lt;br /&gt;
                                                                                 fprintf(stderr, &amp;quot;accept() error: client_sock(%d)\n&amp;quot;, client_sock), exit(-1);&lt;br /&gt;
                                                                 target_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);&lt;br /&gt;
                                                                 if(target_sock == -1)&lt;br /&gt;
                                                                                 fprintf(stderr, socket() error: target_sock(%d)\n&amp;quot;, target_sock), exit(-1);&lt;br /&gt;
                                                                 if(connect(target_sock, (struct sockaddr *)&amp;amp;amp;target_addr, sizeof(target_addr)) == -1)&lt;br /&gt;
                                                                                 fprintf(stderr, &amp;quot;connect() error: target_sock(%d)\n&amp;quot;, target_sock), exit(-1);&lt;br /&gt;
 &lt;br /&gt;
                                                                 sock[0] = client_sock;&lt;br /&gt;
                                                                 sock[1] = target_sock;&lt;br /&gt;
 &lt;br /&gt;
                                                                 pthread_create(&amp;amp;amp;tid, NULL, target, (void *)sock);&lt;br /&gt;
                                                                 pthread_create(&amp;amp;amp;tid, NULL, client, (void *)sock);&lt;br /&gt;
                                                 }&lt;br /&gt;
                                                 return 0;&lt;br /&gt;
                                 default:&lt;br /&gt;
                                                 close(server_sock);&lt;br /&gt;
                                                 return 0;&lt;br /&gt;
                 }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 void *target(void *arg)&lt;br /&gt;
 {&lt;br /&gt;
                 int msg_len;&lt;br /&gt;
                 char msg[MSG_MAX];&lt;br /&gt;
 &lt;br /&gt;
                 int client_sock = ((int *)arg)[0];&lt;br /&gt;
                 int target_sock = ((int *)arg)[1];&lt;br /&gt;
 &lt;br /&gt;
                 while((msg_len = recv(client_sock, msg, MSG_MAX, 0)) != 0){&lt;br /&gt;
                                 msg[msg_len] = &amp;#039;\0&amp;#039;;&lt;br /&gt;
                                 if(send(target_sock, msg, strlen(msg), 0) == -1)&lt;br /&gt;
                                                 break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 pthread_mutex_lock(&amp;amp;amp;mutex);&lt;br /&gt;
                 if(target_sock)&lt;br /&gt;
                                 close(target_sock);&lt;br /&gt;
                 if(client_sock)&lt;br /&gt;
                                 close(client_sock);&lt;br /&gt;
                 pthread_mutex_unlock(&amp;amp;amp;mutex);&lt;br /&gt;
 &lt;br /&gt;
                 pthread_exit(NULL);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void *client(void *arg)&lt;br /&gt;
 {&lt;br /&gt;
                 int msg_len;&lt;br /&gt;
                 char msg[MSG_MAX];&lt;br /&gt;
 &lt;br /&gt;
                 int client_sock = ((int *)arg)[0];&lt;br /&gt;
                 int target_sock = ((int *)arg)[1];&lt;br /&gt;
 &lt;br /&gt;
                 while((msg_len = recv(target_sock, msg, MSG_MAX, 0)) != 0){&lt;br /&gt;
                                 msg[msg_len] = &amp;#039;\0&amp;#039;;&lt;br /&gt;
                                 if(send(client_sock, msg, strlen(msg), 0) == -1)&lt;br /&gt;
                                                 break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 pthread_mutex_lock(&amp;amp;amp;mutex);&lt;br /&gt;
                 if(target_sock)&lt;br /&gt;
                                 close(target_sock);&lt;br /&gt;
                 if(client_sock)&lt;br /&gt;
                                 close(client_sock);&lt;br /&gt;
                 pthread_mutex_unlock(&amp;amp;amp;mutex);&lt;br /&gt;
 &lt;br /&gt;
                 pthread_exit(NULL);&lt;br /&gt;
 }&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;Unknown</name></author>
	</entry>
</feed>