[C 언어] Concurrent Proxy 구현하기

유선·2024년 4월 22일
0

CS

목록 보기
22/25
post-thumbnail

🔥 tiny, Sequential Proxy 구현을 완료했다면 Concurrent Proxy를 구현해보자!
🔗 http://csapp.cs.cmu.edu/3e/proxylab.pdf
🔗 과제 요약
🔗 tiny
🔗 Sequential Proxy

Part II : Dealing with multiple concurrent requests

💡 동시다발적인 요청 처리하기

구현 전 필수!!!! 설정 사항

nop-server.py

#!/usr/bin/python -> #!/usr/bin/python3

필수는 아닌.. 설정 사항


프록시를 실행하다보면 favicon 에러가 뜬다.
이를 없애기 위해
doit() 함수에 에러 조건을 설정한다.
파싱 코드 위에 넣어주면 된다.

    if (!strcasecmp(uri, "/favicon.ico")) // favicon 에러
      return;


위치 확인!

구현하기

나머지 코드는 Sequential Proxy 코드와 동일하다.

main

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);
  }
}
  • 클라이언트의 연결을 비동기적으로 처리하기 위해 각 클라이언트에 대해 새로운 스레드를 생성
  • 스레드가 생성된 후에는 해당 스레드가 클라이언트의 연결을 처리하고, 클라이언트 소켓은 동적으로 할당된 메모리를 통해 전달

thread_func

💡 각 연결을 처리할 스레드 함수

void *thread_func(void *arg) {
  int clientfd = *((int *)arg); // 클라이언트 소켓 파일 디스크립터를 인수로부터 얻음
  free(arg);
  // 기존의 `doit` 함수를 호출하여 클라이언트 요청 처리
  doit(clientfd);

  // 클라이언트 소켓 닫음
  Close(clientfd);

  // 스레드 종료
  pthread_exit(NULL);
}
  • 클라이언트 연결에 대해 새로운 스레드가 생성될 때마다 호출되어 실행
  • 스레드는 해당 클라이언트의 요청을 처리하고 연결을 종료한 후 스레드를 종료

테스트 결과 확인

70점 만점에 55점 점수를 확인했다면!
이제 cache 기능을 구현하러 가쟈!!!! 빠띵!!!!

브라우저 확인법

  1. tiny 폴더에서 실행
    make clean; make
    ./tiny 8000

  2. tiny 상위 폴더, proxy 폴더에서 실행
    make clean; make
    ./proxy 8080


접속하쟈~~!@

추가 수정 사항은 깃허브를 확인해주세요! 😇

profile
Sunny Day!

0개의 댓글