1. HTTP GET 요청과 POST 요청의 가장 큰 차이점은 무엇이며, 이것이 요청 헤더나 데이터 전송에 어떤 영향을 미칩니까?
- GET 요청은 데이터를 URL의 일부(query string)로 전송하지만 POST 요청은 데이터를 요청 본문(body)에 포함합니다.
1) GET 요청의 URL 길이에는 브라우저나 서버에 따라 제한이 있습니다. 이로 인해 전송할 수 있는 데이터의 양이 제한됩니다.
2) POST 요청은'Content-Length'와 'Content-Type' 같은 추가적인 헤더 정보를 필요로 합니다.
2. HTTP 응답 코드 404의 의미는 무엇입니까? 그리고 서버가 요청을 처리할 수 없을 때 반환하는 HTTP 상태 코드는 무엇입니까?
- HTTP 응답코드 404는 "Not Found"를 의미합니다. 이 코드는 서버가 요청된 리소스를 찾을 수 없을 때 반환됩니다.
- 서버가 요청을 처리할 수 없을 때 반환하는 HTTP 상태코드는 500입니다. 이 코드는 "Internal Server Error"를 나타냅니다.
3. 파일 디스크립터(File Descriptor)란 무엇인지 간단히 설명하고 UNIX/Linux 시스템에서 표준입출력/에러의 파일 디스크립터 번호를 쓰세요.
- 파일 디스크립터는 운영체제에서 파일이나 다른 입출력 리소스에 대한 접근을 추상화하는데 사용되는 정수입니다.
파일 디스크립터를 통해 운영체제는 파일, 파이프, 소켓 등 다양한 입출력 리소스를 일관된 방식으로 관리할 수 있습니다.
예를 들어, 파일을 열면 운영체제는 해당 파일을 가리키는 파일 디스크립터를 프로그램에 제공합니다.
UNIX/Linux 시스템에서 표준입력의 파일 디스크립터 번호는 0, 표준출력은 1, 그리고 표준에러는 2 입니다.
4. TCP에서의 '3-way handshake' 절차를 설명하세요.
- TCP의 '3-way handshake'는 연결 설정 과정에서 사용되는 절차이다. 이 과정은 다음과 같이 세 단계로 이루어진다.
1) 클라이언트가 서버에 SYN(Synchronize) 패킷을 보내 연결 요청을 한다.
2) 서버는 SYN-ACK(Synchronize-Acknowledge) 패킷으로 응답하여 연결 요청을 받았음을 알리고, 자신도 연결 준비가 되었음을 나타낸다.
3) 클라이언트는 ACK(Acknowledge) 패킷을 서버에 보내 연결을 확정한다.
5. TCP와 UDP에서 패킷 손실 시 대처 방법에는 어떤 차이가 있나요?
- TCP는 패킷 손실이 발생하면 자동으로 재전송을 시도한다.
수신자는 받은 패킷에 대해 확인 응답(ACK)을 보내고, 송신자는 ACK를 받지 못한 패킷을 재전송한다.
반면, UDP는 패킷 손실에 대해 자체적으로 대처하지 않는다.
UDP는 확인 응답이나 재전송 기능이 없어, 패킷 손실이 발생하면 이를 어플리케이션 레벨에서 처리해야한다.
6. 다음 ANSI C프로그램에서 출력되는 내용은 무엇인가요?
#include <stdio.h>
int main(int argc, char *argv[])
{
int x = 1, z[2] = {10, 11};
int *p = NULL;
p = &x;
*p = 10;
p = &z[1];
*(&z[0] + 1) += 3;
printf("%d, %d, %d\n", x, z[0], z[1]);
return 0;
}
10, 10, 14
12. 동시성 프로그래밍
12.1 프로세스를 사용한 동시성 프로그래밍
부모 프로세스는 listen, 자식을 생성(fork)해 자식을 통해 새로운 클라이언트와 데이터를 주고 받는다.
부모는 자식을 생성하고 필요하지 않은 식별자를 닫음 - 자식 : 듣기 식별자(listenfd) / 부모 : 연결 식별자(connfd)
과 정
12.1.1 프로세스 기반 동시성 서버
프로세스 기반 동시성 서버를 만드는데 중요한 사항이 있다.
- 서버들은 대개 장시간 동안 돌아가므로 좀비 자식을 청소하는 SIGCHLD 핸들러를 포함해야 한다.
- 부모와 자식은 자신의 connfd를 닫아야 한다. 메모리 누수를 방지하기 위해 부모는 특히 닫는 것이 중요하다.
- 부모와 자식의 connfd가 모두 닫힐 때까지 클라이언트와의 연결은 종료되지 않는다.
if (Fork() == 0) {
Close(listenfd); // 자식의 listenfd를 닫음
echo(connfd); // echo를 실행
Close(connfd); // 자식의 connfd를 닫음
exit(0);
}
Close(connfd); // 부모의 connfd를 닫음 (**중요!!**)
12.1.2 프로세스의 장단점
장점
- 부모와 자식 사이에 상태 정보를 공유한다.
- 한 개의 프로세스가 다른 프로세스의 가상 메모리를 접근하는 것이 불가능하다.(혼란스러운 오류를 제거할 수 있음)
단점
- 별도의 주소공간(쓰레드)은 프로세스가 상태 정보를 공유하는 것을 어렵게 한다.(IPC 메커니즘을 사용해야 함)
- 프로세스 제어와 IPC의 오버헤드가 크기 때문에 느려지는 경향이 있다.
12.2 I/O 다중화를 이용한 동시성 프로그래밍
한 개의 서버에 두 개의 독립적인 I/O 이벤트에 대해 응답하기 위해 I/O 다중화 기술을 적용시킨다.
select 함수를 사용해서 커널에게 한 개 이상의 I/O이벤트가 발생한 후에만 프로세스에게 제어를 주는 것으로 진행한다.
코드
FD_ZERO(&read_set); // read_set을 0으로 초기화
FD_SET(STDIN_FILENO, &read_set); // read_set에서 stdin을 1로 세팅
FD_SET(listenfd, &read_set); // read_set에서 listenfd를 1로 세팅
while (1) {
ready_set = read_set; // read_set을 직접 사용하면 안되기 때문에 복사본을 저장
// Select() : 읽기 또는 쓰기 동작을 수행할 수 있는 식별자를 찾아냄
Select(listenfd+1, &ready_set, NULL, NULL, NULL);
if (FD_ISSET(STDIN_FILENO, &ready_set)) // stdin이 1이라면 아래를 수행
command(); /* Read command line from stdin */
if (FD_ISSET(listenfd, &ready_set)) { // listenfd가 1이라면 아래를 수행
clientlen = sizeof(struct sockaddr_storage);
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
echo(connfd); /* Echo client input until EOF */
Close(connfd);
}
}
12.2.1 I/O 다중화에 기초한 동시성 이벤트 기반 서버
논리흐름을 상태 머신(State Machine)으로 모델링하는 것이다.
상태 머신은 상태, 입력 이벤트, 상태와 입력 이벤트를 상태로 매핑하는 전환의 집합이다.
코드
#include "csapp.h"
// pool 구조체 정의
typedef struct {
int maxfd; // read_set에서 가장 큰 fd
fd_set read_set; // fd의 집합
fd_set ready_set; // 읽을 수 있는 fd의 집합
int nready; // 실행해야 되는 fd의 개수
int maxi; // 클라이언트 배열에서 가장 큰 인덱스
int clientfd[FD_SETSIZE]; // 활성화된 클라이언트 fd의 배열
rio_t clientrio[FD_SETSIZE]; // 활성화된 읽기 버퍼의 배열
} pool;
static int byte_cnt = 0; // 서버가 받은 바이트 수를 카운트
int main(int argc, char **argv) {
int listenfd, connfd;
socklen_t clientlen;
struct sockaddr_storage clientaddr;
static pool pool;
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(0);
}
listenfd = Open_listenfd(argv[1]);
init_pool(listenfd, &pool); // pool을 초기화
while (1) {
pool.ready_set = pool.read_set;
pool.nready = Select(pool.maxfd+1, &pool.ready_set, NULL, NULL, NULL);
if (FD_ISSET(listenfd, &pool.ready_set)) { // listenfd가 1이면 아래를 실행
clientlen = sizeof(struct sockaddr_storage);
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
add_client(connfd, &pool); // pool에 클라이언트와 연결된 connfd를 추가
}
check_clients(&pool); // 클라이언트 데이터 전송 및 반환을 체크
}
}
init_pool 함수
void init_pool(int listenfd, pool *p) {
int i;
p->maxi = -1; // pool이 비어있기 때문에 -1로 초기화
for (i=0; i< FD_SETSIZE; i++)
p->clientfd[i] = -1; // 반복문을 돌면서 -1로 초기화
p->maxfd = listenfd; // read_set에는 초기에 listenfd만 있음
FD_ZERO(&p->read_set); // 0으로 초기화
FD_SET(listenfd, &p->read_set); // listenfd를 1로 세팅
}
add_client 함수
void add_client(int connfd, pool *p) {
int i;
p->nready--; // 읽기 준비된 목록에서 1개를 빼서 사용하기 때문에 1개를 감소시킴
for (i = 0; i < FD_SETSIZE; i++) // pool에 가능한 공간이 있는지 확인함
if (p->clientfd[i] < 0) {
p->clientfd[i] = connfd; // pool에 connfd를 추가함
Rio_readinitb(&p->clientrio[i], connfd);
FD_SET(connfd, &p->read_set); // read_set에 connfd를 1로 세팅
if (connfd > p->maxfd) // 새로 추가했기 때문에 pool의 최대를 비교해보고 변경
p->maxfd = connfd;
if (i > p->maxi) // 새로 추가했기 때문에 pool의 최대를 비교해보고 변경
p->maxi = i;
break;
}
if (i == FD_SETSIZE) // 만약 클라이언트가 들어올 공간이 없다면 에러 반환
app_error("add_client error: Too many clients");
}
check_clients 함수
void check_clients(pool *p) {
int i, connfd, n;
char buf[MAXLINE];
rio_t rio;
// maxi(클라이언트 배열의 크기(가장 큰 인덱스))보다 같거나 작고, 활성화된 상태이면 아래를 수행
for (i = 0; (i <= p->maxi) && (p->nready > 0); i++) {
connfd = p->clientfd[i];
rio = p->clientrio[i];
// 유효한지 확인하고, connfd를 1로 세팅
if ((connfd > 0) && (FD_ISSET(connfd, &p->ready_set))) {
p->nready--;
if ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
byte_cnt += n;
printf("Server received %d (%d total) bytes on fd %d\n",
n, byte_cnt, connfd);
Rio_writen(connfd, buf, n);
}
else {
Close(connfd); // 사용한 후에는 소켓을 닫고
FD_CLR(connfd, &p->read_set); // pool에서 비우고
p->clientfd[i] = -1; // clientfd를 -1로 초기화
}
}
}
}
'크래프톤 정글 - TIL' 카테고리의 다른 글
크래프톤 정글 5기 TIL - Day 52(알고리즘) (0) | 2024.05.13 |
---|---|
크래프톤 정글 5기 TIL - Day 50(키워드 정리) (0) | 2024.05.09 |
크래프톤 정글 5기 TIL - Day 47(CS:APP) (0) | 2024.05.07 |
크래프톤 정글 5기 TIL - Day 46 (2) | 2024.05.04 |
크래프톤 정글 5기 TIL - Day 45 (0) | 2024.05.03 |