일반적으로 Socket이라고 하면 BSD 소켓을 말합니다. (POSIX 기준으로 버클리에서 만든 네트워크 인터페이스)
TCP / IP 프로토콜을 기반으로 개발된 소켓 인터페이스이다. 네트워크 통신을 위한 소프트웨어 인터페이스라고도 합니다.
커널 관점에서 소켓은 통신을 위한 끝점이고, 식별자를 가지는 열린 파일로 생각합니다.

소켓은 다음과 같은 클라이언트 - 서버 방식으로 전개된다. TCP 기반이므로 accept가 와여 소켓 연결을 허용하며, EOF 예외처리가 생길 시, 서버를 닫습니다.

sokaddr_in 타입의 16바이트 구조체에 저장된다.
sin_family 필드: AF_INET
sin_port 필드: 16비트 포트 번호
sin_addr 필드: 32비트 IP주소.
→ IP주소와 포트 번호는 항상 네트워크 바이트 순서로 저장합니다.
connect, bind, accept 함수는 프로토콜에 특화된 소켓 주소 구조체를 가리키는 포인터를 필요로 합니다.
클라이언트와 서버는 소켓 식별자를 생성하기 위해서 socket 함수를 사용한다.
만약, 소켓을 끝점으로 만들고 싶다면, 다음과 같이 하드코드된 인자로 socket함수를 호출하면 된다.
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
클라이언트는 connect 함수를 호출해서 서버와의 연결을 수립한다.
#include <sys/socket.h>
int connect(int clientfd, const struct sockaddr *addr, socklen_t addrlen);
소켓 주소 addr의 서버와 인터넷 연결을 시도한다. connect 함수는 연결이 성공할 때까지 블록되어 있거나 에러가 발생한다. 만약, 성공한다면 clientfd 식별자가 이제 읽거나 쓸 준비가 되었고, 소켓 쌍으로 규정된다.
남아 있는 소켓 함수(bind, listen, accept)는 서버가 클라이언트와 연결을 수립하기 위해 사용한다.
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
커널에게 addr에 있는 서버의 소켓 주소를 소켓 식별자 sockfd와 연결하는 것을 물어본다. soket과 connect 에서와 마찬가지로, 최상의 방법은 getaddrinfo를 이용해서 bind할 인자들을 제공하는 것이다.
클라이언트는 연결 요청을 개시하는 능동적 개체이다. 반면, 서버는 수동적이다.
#include <sys/socket.h>
int listen(int sockfd, int backlog);
기본적으로 커널은 socket 함수가 만든 식별자는 한 연결의 클라이언트 쪽 끝에서 존재하는 능동 소켓에 대응한다. 서버는 listen 함수를 호출해, 식별자를 클라이언트 대신에 서버가 사용하게 될 것이라고 알려준다.

sockfd를 능동 소켓에서 듣기 소켓으로 변환하며, 듣기 소켓은 클라이언트로부터의 연결 요청을 승락할 수 있다.
backlog는 커널이 요청들을 거절하기 전에 큐에 저장해야 하는 연결의 수에 대한 정보를 제공한다.
서버는 해당 함수를 호출해서 클라이언트로부터의 연결 요청을 기다린다.
#include <sys/socket.h>
int accept(int listenfd, struct sockaddr *addr, int *addrlen);
클라이언트로부터의 연결 요청이 듣기 식별자 listenfd에 도달하기를 기다리고, addr 내의 클라이언트의 소켓 주소를 채우고, Unix I/O 함수들을 이용해서 클라이언트와 통신하기 위해 사용될 수 있는 연결 식별자를 리턴한다.