프록시 서버를 구성하고 있는데 궁금한 점이 있습니다.
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;
}
이게 에코프록시 서버 코드구요..
여기서 좀 더 발전시켜서 실제로 구글 같은 웹서버랑 연결하는 프록시 서버로 만들려고 하는데요.
어떻게 발전시켜야 하는지 잘 모르겠는데, 조언 좀 주실수 있으신가요?
코드를 본문에
코드를 본문에 포함하실때는 코드블럭을 사용해주세요;;
코드를 읽어보진 않았지만, 우선 구현하시려는 기능을 생각해보시고,
로직을 정리하신 후에, 기능에 필요한 코드 예제를 찾아보시기 바랍니다.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
댓글 달기