버클리 대학에서 UNIX 4.2 BSD 커널에서 사용하기 위해 만든 소켓 인터페이스
TCP/IP 기반 네트워크 통신 // TCP/IP 뿐만 아니라 다양한 네트워크 프로토콜을 지원
현재 네트워크 프로그래밍의 표준이 됨
-> 소켓이라고 하면 일반적으로 BSD 소켓을 의미
**
엔드포인트 : 네트워크 통신을 할 수 있는 한 쪽 끝을 의미
Ex) www.quilzy.shop:8080, www.quizly.shop:3004
IP 주소 : 네트워크상의 기기를 식별할 때 사용 Ex) 클라이언트1, 클라이언트2, 퀴즐리 서버
포트 번호 : 특정 기기 내의 특정 프로세스나 서비스 식별 Ex) 좌표를 위한 소켓, 채팅을 위한 소켓,
소켓 인터페이스란
응용 계층과 전송 계층 사이의 인터페이스
네트워크 통신의 복잡성을 추상화하여 단순한 인터페이스 제공
- IP 주소, 포트번호 관리, 패킷 형성과 전송, 오류 검충 및 재전송 등의 저수준의 작업을 직접하지 않고
Socket(), bind(), listen(), accept(), connect() 등의 함수를 사용하여 쉽게 사용하게 함
이 함수들은 시스템 콜 함수
소켓 인터페이스는 두 호스트 간의 논리적 연결을 통해 통신을 수행한다.
- 논리적 연결이란 지속적인 물리적인 연결이 아닌 양쪽 엔드포인트의 상태 정보를 유지하는 것을 의미한다.
이 상태 정보는 IP, PORT, 시퀀스 번호 등을 포함
소켓(파일)이란
운영체제가 관리하는 리소스 // 파일을 의미
유닉스/리눅스 시스템에서 파일 디스크립터를 통해 관리된다.
소켓 통신을 위한 연결 정보를 저장한다.
- 로컬 엔드포인트
- 원격 엔드포인트
- 프로토콜 정보
- 연결 상태 정보 등등
** 소켓 파일은 추상적인 개념, 실제로 디스크에 존재하는 파일이 아님
그러므로 소켓 파일은 커널 내부의 데이터 구조이다. 즉, 커널 메모리 공간에 데이터 구조 형태로 존재한다.
소켓 버퍼에 데이터를 쓰거나 읽어오는 것은 커널 메모리 공간에 데이터를 쓰거나 읽어오는 것이다.
BSD 소켓 인터페이스를 활용한 소켓 연결 과정
** 서버 **
1. 서버 소켓 생성
- 서버는 socket() 시스템 콜 함수를 통해 소켓 파일을 생성한다.
2. bind() 함수 실행
- 서버는 bind() 시스템 콜 함수를 호출하여 특정 IP 주소와 포트에 소켓 파일을 바인딩함
즉, 서버 엔드 포인트 정보(IP와 PORT)를 소켓 파일간의 연결을 생성
서버가 클라이언트로부터 연결 요청을 받을 IP와 포트를 지정하는 과정
3. listen() 함수 실행
- 서버는 listen() 시스템 콜 함수를 호출하여 듣기 소켓으로 변환된다.
- 커널이 SYN 패킷을 처리할 준비를 함
즉, 엔드포인트로 들어오는 SYN 패킷을 자동으로 감지할 수 있는 '수신대기' 상태가 된다.
Socket() 함수를 이용해 생성한 소켓 파일은 새로운 연결을 위해 사용된다.
4. accept() 함수 실행
- 서버는 accept() 시스템 콜 함수를 호출하여 연결 요청이 들어오기를 기다린다.
즉, 실제 SYN 패킷을 자동으로 감지하고 처리한다.
5. 클라이언트로부터 SYN 패킷 도착
- 커널이 자동으로 TCP 3-way handshake를 수행한다. 수행이 완료되면 accept() 함수 호출가
반환된다, 이 때 새로운 클라이언트와의 연결을 수락할 수 있는 새로운 소켓을 반환
새로운 소켓은 SYN 패킷을 전송한 클라이언트와의 통신을 위한 새로운 소켓 파일이다.
6. 프로세스의 파일 디스크립터 테이블에 해당 소켓 파일 파일 디스크립터 저장
- 서버와 클라이언트는 논리적으로 연결됨
- 서버는 해당 파일 디스크립터를 사용해서 상대방과 데이터를 주고 받는다.
7. 서버와 클라이언트는 send()/recv() 시스템 콜 함수를 활용하여 데이터를 주고 받는다.
8. 서버와 클라이언트는 close() 시스템 콜 함수를 활용하여 소켓 연결을 해제할 수 있다.
-------------------------------------------------------------------------------
** 클라이언트 **
1. 클라이언트 socket() 시스템 콜 함수를 호출한다.
- 클라이언트는 socket() 시스템 콜 함수를 호출하여 소켓 파일을 생성한다.
2. 클라이언트는 connect() 시스템 콜 함수를 호출한다.
- 클라이언트는 connect() 시스템 콜 함수를 호출하여 소켓 파일에 서버의 IP와 포트번호를 지정한다.
그리고 운영체제는 자동으로 SYN 패킷을 생성해서 서버의 IP와 포트번호에 SYN 패킷 전송
3. TCP 3-way handshake 완료하여 connect()함수 반환
- 성공적으로 연결을 완료
- 서버와 클라이언트는 send()/recv() 시스템 콜 함수를 활용하여 데이터를 주고 받는다.
데이터 송수신 과정
소켓 통신은 소켓 파일의 버퍼를 사용하여 데이터를 송수신
이 버퍼는 커널 공간에 위치하며 OS가 관리
** 소켓 파일은 추상적인 개념, 실제로 디스크에 존재하는 파일이 아님
그러므로 소켓 파일은 커널 내부의 데이터 구조이다. 즉, 커널 메모리 공간에 데이터 구조 형태로 존재한다.
소켓 버퍼에 데이터를 쓰거나 읽어오는 것은 커널 메모리 공간에 데이터를 쓰거나 읽어오는 것이다.
// 소켓 버퍼는 소켓 파일에 존재하기 때문, Ex) 소켓 구조체 안에 소켓 버퍼 필드 존재
응용 프로그램이 데이터를 보낼 때, write()/send() 시스템 콜을 통해 서버의 소켓 버퍼에 데이터를 씀
OS가 이 버퍼의 데이터를 네트워크를 통해 전송
- Rio_writen() 래퍼 함수를 사용 // write() 시스템 콜의 래퍼 함수
네트워크로부터 데이터가 도착하면 OS는 이를 해당 소켓의 소켓 버퍼에 저장
응용 프로그램은 read()/recv() 시스템 콜을 통해 이 버퍼로부터 데이터를 읽어온다.
- rio_readlineb() 래퍼 함수를 사용하여 한 줄씩 읽음 // read() 시스템 콜의 래퍼 함수
**
래퍼 함수란 원래 함수의 기능을 수행하면서 추가적인 기능을 제공하는 함수