1. 소켓 인터페이스의 주요 특징
ㅇ 특정 운영체제 및 프로그램 언어에 의존적으로(종속적으로) 동작함
- 소켓 인터페이스 그 자체는, TCP/IP 표준이 아님
- 소켓 API는 운영체제에서 제공됨
ㅇ 소켓은 기본적으로 네트워킹을 위한 I/O (입출력) 임
- 응용 프로그램과 통신 프로토콜들(TCP,UDP 등)과의 인터페이스(API) 역할을 함
ㅇ 클라이언트/서버 모델에 기초함
2. 소켓 호출의 형식
※ 소켓 시스템 호출 (Socket System Call) 이란?
- 소켓 동작(생성,바인딩,연결,대기,허용,읽기,쓰기,끊음 등)을 위한,
- 시스템 API 인터페이스에 대한 호출 형식들
ㅇ s1 = socket() : 아직 연결되지 않은 새로운 소켓의 생성
- 소켓 구조체 변수 선언 및 초기화 등
#include <sys/socket.h>
int socket(int domain, int type, int protocol)
. 소켓 생성 성공시 파일 디스크립터(0이 아닌 정수)를 반환, 실패시 -1 반환
ㅇ bind(s1, < 로컬 IP주소 : 포트번호 > ) : 로컬 소켓에 이름(주소) 부여
- 생성된 소켓에, 소켓주소(로컬 IP 주소 및 포트 번호) 할당
- int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);
. 성공시 0 반환, 실패시 -1 반환
ㅇ listen(s1, ... ) : 누군가 생성한 소켓과의 커넥션을 맺기를 기다림
- 소켓 커넥션을 기다림 (대기상태로 들어가게 됨)
#include <sys/type.h>
int listen(int sockfd, int backlog);
. 성공시 0 반환, 실패시 -1 반환
. backlog : 소켓 연결 대기 큐
ㅇ connect(s1, < 원격 IP주소 : 포트번호 > ) : 원격 호스트와의 TCP 소켓 연결 (커넥션) 요청
- 로컬의 소켓과 원격 호스트 소켓 간의 TCP 커넥션 생성
ㅇ s2 = accept(s1) : 로컬 소켓에 소켓 연결 (커넥션) 요청의 허용
- 소켓 요청에 대한 허락이 이루어지고, 실제 통신용 소켓이 생성됨
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
. 성공시 0 반환, 실패시 -1 반환
- TCP 프로토콜 수준에서, TCP의 3단계 핸드세이킹으로, 연결 절차가 이루어지면,
. 새로운 소켓을 생성하고, 이 소켓을 이용하여 상호 데이터를 주고받음
. 기존 소켓은, 새로운 클라이언트 접속을 수용하는데 계속 사용(대기)됨
ㅇ n = read(s1, buffer, n) : 소켓으로부터 버퍼에 n 바이트 읽기 시도
ㅇ n = write(s1, buffer, n) : 소켓으로부터 버퍼에 n 바이트 쓰기 시도
ㅇ close(s1) 또는 closesocket() : TCP 커넥션을 완전히 끊음
- close (유닉스/리눅스), closesocket (윈도우즈)
ㅇ shutdown(s1, < side > ) : TCP 커넥션의 정해준 입출력 만 닫음
- TCP 연결 종료 중 반 종료(Half Close)에 이용되는 함수
#include <sys/socket.h>
int shutdown(int sock, int howto);
. 성공시 0 반환, 실패시 -1 반환
. 종료 방법 구분
.. SHUT_RD : 입력 스트림 종료
.. SHUT_WR : 출력 스트림 종료
.. SHUT_RDWR : 입출력 스트림 종료
ㅇ getsockopt(s1, ... ) : 내부 소켓 설정 옵션값을 읽음
ㅇ setsockopt(s1, ... ) : 내부 소켓 설정 옵션값을 변경
3. 소켓 호출의 순서
ㅇ TCP 서버에서의 소켓 함수 호출 순서
- socket() -> bind() -> listen() -> accept() -> read()/write() -> close()