그래서. 창구가 뭔데? 실제로 구멍이 나 있는 것도 아니고..!
1) (CSAPP 10.1 856p) 리눅스에서 파일은 연속된 m개의 바이트이다.
2) (CSAPP 10.1 856p) 네트워크, 디스크, 터미널 같은 모든 I/O 디바이스들은 파일로 모델링되며, 모든 입력과 출력은 해당 파일을 읽거나 쓰는 형식으로 수행된다.
3) (CSAPP 10.2 857p) 소켓은 "네트워크상의 다른 프로세스와 통신하기 위해 사용되는 파일"이다.
파일은 입출력의 추상화이고, 소켓은 다른 프로세스와 통신하기 위한 "파일"이다.
/*Ip socket address structure*/
struct sockaddr_in{
uint16_t sin_family;
uint16_t sin_port; /*16비트 포트 번호*/
struct in_addr sin_addr; /*32비트 IP 주소*/
unsigned char sin_zero[8];
}
struct sockaddr{
uint16_t sa_family;
char sa_data[14]; /* address data */
}
typedef struct sockaddr SA;
cf. connect: 클라이언트가 서버와의 연결을 수립하기 위해
cf. bind, accept: 서버가 클라이언트와 연결을 수립하기 위해
cf. 소켓 식별자?
소켓도 일종의 "파일"이라고 했다.
마치 프로세스에도 pid라는 고유번호가 있는 것처럼, 소켓(파일)에도 고유 번호가 필요하다. 그것이 바로 소켓 식별자이다. (fd = file descriptor )
int socket(int domain, int type, int protocol);
/*리턴 값이 음수이면 error, 그렇지 않으면 소켓 식별자(int 형)가 제대로 생성된 것이다. */
클라이언트는 서버에게 요청(request)를 보내면서 둘 사이의 통신 사인을 보내긴 하지만, 서버가 요청을 받아들여야(accept)해야 둘 사이의 통신 채널이 만들어지는 것이다.
int connect(int clientfd, const struct sockaddr *addr, socklen_t addrlen);
/*connect가 성공하면 0 리턴, 실패하면 -1 리턴*/
1) int clientfd: 클라이언트가 socket함수의 결과로 리턴받은 클라이언트 소켓 식별자
2) const struct sockaddr *addr: 서버 소켓의 주소
3) socklen_t addrlen: sizeof(sockaddr_in)
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*bind가 성공하면 0 리턴, 실패하면 -1 리턴*/
int listen(int sockfd, int backlog);
/*listen가 성공하면 0 리턴, 실패하면 -1 리턴*/
1) 서버는 클라이언트의 요청이 오기 전부터 열려 있어야 한다.
2) 따라서 특정 클라이언트와의 통신을 위한 소켓뿐만 아니라, 임의의 클라이언트로부터 오는 요청들을 받아올 "웰컴 소켓"이 필요하다.
3) CS APP에서는 이 소켓의 식별자를 listenfd라는 변수 나타낸다.
1) int sockfd: 듣기 식별자로 지정할 소켓 식별자
2) int backlog: 커널이 요청들을 거절하기 전에 "큐"에 저장해야 하는 연결의 수에 대한 정보
int accept(int listenfd, struct sockaddr* addr, int *addrlen);
/*리턴 값이 음수이면 error, 그렇지 않으면 소켓 식별자(int 형)가 제대로 생성된 것이다. */
듣기 식별자(listenfd) vs. 연결 식별자(connfd)
1. 듣기 식별자는 한번 생성되면, 서버가 살아있는 한 계속 존재한다.
2. 연결 식별자는 서버가 클라이언트로부터 오는 연결 요청을 수락할 때마다 생성된다.
잘 보고 갑니다~~