3.5 TCP 소켓
UDP는 내부 상태가 없고 연결을 유지하지 않으며 신뢰성을 보장하지 않는다. 따라서 호스트마다 하나의 소켓만 있으면 데이터그램을 보내고 받기를 다 할 수 있다. 반면 TCP는 신뢰성을 보장하며, 데이터를 주고받기 위해 두 호스트 사이에 연결을 맺어 두어야 한다. 추가로, 누락된 패킷을 재전송하기 위해 상태 정보를 유지하고 이를 어딘가 저장해 두어야 한다. 버클리 소켓 API에선 socket 자체에 그 연결 정보를 기록하는데, 이는 곧 호스트가 각 TCP 연결마다 별개의 독자적 소켓을 하나씩 유지해야 한다는 뜻이다.
TCP에서 클라이언트와 서버 사이에 연결을 초기 수립하려면 3-웨이 핸드셰이킹을 거쳐야 한다. 서버가 핸드셰이킹 첫 단계를 받으려면, 먼저 소켓을 만들어 두고 이 소켓을 특정 포트에 바인딩한 뒤 들어오는 핸드셰이킹을 리스닝(listening)해야 한다. socket()으로 소켓을 만들고 bind()로 바인딩 후, listen()으로 리스닝을 시작한다.
int listen(SOCKET sock, int backlog);
sock은 리스닝 모드에 둘 소켓을 가리킨다. 소켓이 리스닝 모드에 있으면 외부에서 들어오는 TCP 핸드셰이킹 첫 단계 요청을 받아 이를 대기열에 저장해 둔다. 이후 프로세스가 accept()를 호출하면 저장해 둔 연결 요청의 그다음 핸드셰이킹 단계를 속행한다.