🔥 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

접속하쟈~~!@
추가 수정 사항은 깃허브를 확인해주세요! 😇