🔥 tiny, Sequential Proxy 구현을 완료했다면 Concurrent Proxy를 구현해보자!
🔗 http://csapp.cs.cmu.edu/3e/proxylab.pdf
🔗 과제 요약
🔗 tiny
🔗 Sequential Proxy
💡 동시다발적인 요청 처리하기
nop-server.py
#!/usr/bin/python
-> #!/usr/bin/python3
프록시를 실행하다보면 favicon 에러가 뜬다.
이를 없애기 위해
doit() 함수
에 에러 조건을 설정한다.
파싱 코드 위에 넣어주면 된다.
if (!strcasecmp(uri, "/favicon.ico")) // favicon 에러
return;
위치 확인!
나머지 코드는 Sequential Proxy 코드와 동일하다.
int main(int argc, char **argv) {
int listenfd;
int *clientfd; // 서버 및 클라이언트 소켓 파일 디스크립터
char hostname[MAXLINE], port[MAXLINE]; // 클라이언트 호스트네임 및 포트번호
socklen_t clientlen; // 클라이언트 주소 구조체 크기
struct sockaddr_storage clientaddr; // 클라이언트 주소 구조체
pthread_t tid; // 스레드 ID를 저장할 변수
// 명령행 인수 확인
if (argc != 2) { // 인수 개수가 2가 아니면 오류 메시지 출력
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
// 클라이언트 연결 수신 소켓 생성
listenfd = Open_listenfd(argv[1]);
// 클라이언트 요청 수락 및 처리
while (1) {
clientlen = sizeof(clientaddr); // 클라이언트 주소 구조체 크기 설정
clientfd = Malloc(sizeof(int));
*clientfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // 연결 수락
Getnameinfo((SA *)&clientaddr, clientlen, hostname, MAXLINE, port, MAXLINE, 0); // 클라이언트 호스트네임 및 포트번호 추출
printf("Accepted connection from (%s, %s)\n", hostname, port); // 연결 확인 메시지 출력
// 클라이언트 연결을 처리할 새로운 스레드 생성
pthread_create(&tid, NULL, thread_func, clientfd);
// 스레드를 따로 분리하여 메모리 누수를 방지하기
pthread_detach(tid);
}
}
💡 각 연결을 처리할 스레드 함수
void *thread_func(void *arg) {
int clientfd = *((int *)arg); // 클라이언트 소켓 파일 디스크립터를 인수로부터 얻음
free(arg);
// 기존의 `doit` 함수를 호출하여 클라이언트 요청 처리
doit(clientfd);
// 클라이언트 소켓 닫음
Close(clientfd);
// 스레드 종료
pthread_exit(NULL);
}
70점 만점에 55점 점수를 확인했다면!
이제 cache 기능을 구현하러 가쟈!!!! 빠띵!!!!
tiny 폴더에서 실행
make clean; make
./tiny 8000
tiny 상위 폴더, proxy 폴더에서 실행
make clean; make
./proxy 8080
접속하쟈~~!@
추가 수정 사항은 깃허브를 확인해주세요! 😇