기본 소켓 시스템 함수 (연결형)
System Program/socket 2014. 3. 3. 09:181. socket() 함수
int socket(int domain, int type, int protocol);
성공하면 파일 디스크립터을 리턴, 에러가 발생하면 '-1'을 리턴
1.1. domain 매개 변수
도메인 |
통신수단 |
응용프로그램 간의 통신 |
주소포멧 |
주소구조체 |
AF_UNIX |
커널 내부 |
동일 호스트 |
경로명 |
sockaddr_un |
AF_INET |
IPv4 이용 |
IPv4로 연결된 호스트 |
32비트 주소 + 16비트 포트 번호 |
sockaddr_in |
AF_INET6 |
IPv6 이용 |
IPv6로 연결된 호스트 |
128비트 주소 16비트 포트 번호 |
sockaddr_in6 |
1.2. type 매개 변수
종류 |
설명 |
SOCK_STREAM |
연결지향적 양방향 신뢰성 있는 통신 방식 |
SOCK_RAW |
socket API에 의한 데이터 가공없이 데이터를 받고자 할 때 사용 |
SOCK_DGRAM |
SOCKET_STREAM과 상반되는 개념 |
1.3. protocol 매개 변수
IPPROTO_TCP : TCP 프로토콜로 AF_INET 도메인과 SOCK_STREAM 유형 사용 시.
IPPROTO_UDP : UDP 프로토콜로 AF_INET 도메인과 SOCK_DGRAM 유형 사용 시.
IPPROTO_RAW : SOCK_RAW 사용하는 경우 시
일반적으로 '0'을 설정, 자세한 설명은 man page를 참조하는 것이 좋다.
2. bind() 시스템 함수
소켓을 주소에 결속한다. 아래 sockaddr 구조에는 결속된 주소 정보를 담고 있다.
전화기에 비유하자면 전화번호를 전화국 (커널)에 등록하는 절차에 해당한다.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
성공하면 '0'을 리턴, 에러가 발생하면 '-1'을 리턴
domain 매개 변수 표, 5번째 열에 보여지는 것처럼 도메인에 따라 주소체계가 모두 다르다.
모두 다른 주소체계를 위의 sockaddr 구조체를 통해서 통일화할 수 있다.
sockaddr 구조체는 아래와 같다.
sa_family_t sa_family; /* 주소 패밀리 (AF_* 상수) */
char sa_data[14]; /* 소켓 주소 (소켓도메인에 따라 크기가 변한다) */
};
3. listen() 시스템 함수
커널에게 bind에서 결속한 주소로 연결을 받기위해 대기 중임을 알린다.
전화기로 따지면 전화를 받을 준비가 모두된 상태를 의미한다.
이처럼 연결이 되기를 기다리는 형태의 동작을 수동형 연결이라 하며, 일반적으로 서버쪽의 동작이다.
int listen(int sockfd, int backlog);
성공하면 '0'을 리턴, 에러가 발생하면 '-1'을 리턴
위에서 backlog 값은 연결이 지연된 요청에 대한 개수를 리턴한다.
리눅스에서 이 값은 128로 설정되어 있으며, /proc/sys/net/core/somaxconn 파일을 통해서 런타임으로
한도값을 설정할 수 있다.
4. accept() 시스템 함수
연결을 요청한 소켓을 수락하는 동작이다.
전화기로 따지면 수화기를 드는 동작에 해당한다.
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
성공하면 파일 디스크립터를 리턴하고, 에러가 발생하면 '-1'을 리턴
accept에서 핵심은 connect() 호출한 상대방의 소켓과 새로운 연결을 맺을 소켓을 생성하는 것이다.
따라서 socket()함수를 통해서 생성된 소켓은 연결을 계속 기다리는 소켓으로 남아있고,
accept()를 통해서 새로 생성된 소켓을 통해서 connect() 호출한 쪽과 통신을 할 수 있다.
따라서 accept()함수의 리턴값에 새로운 소켓을 리턴하는 것이다.
뒤이은 sockaddr 구조체 포인터를 통해서 connect()을 요청한 쪽의 주소를 얻을 수 있다.
상대방의 주소가 필요없을 경우, 각각 NULL, '0'을 설정하면 된다.
5. connect() 시스템 함수
위에서 listen()으로 대기중인 소켓에 연결을 요청할 때 사용하는 시스템 함수이다.
능동형 연결에 해당하며, 일반적으로 클라이언트쪽의 동작이다.
int connect(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
성공하면 '0'을 리턴하고, 에러가 발생하면 '-1'을 리턴
클라이언트쪽에서는 별도의 bind() 동작을 통해서 주소를 결속하는 작업은 없다.
connect()함수의 주소관련 매개변수를 통해서 bind() 동작과 유사한 동작은 포함되어 있다.
6. 소켓을 통한 데이터 전송 및 수신 함수
연결 지향형 소켓 응용에서는 read()/write()함수를 통해서 데이터를 송수신한다.
여기서 중요한 점은 양단간에 연결이 끊어졌을 때, 가장 기본적인 에러처리에 대한 것이다.
연결이 끊어진 곳에 데이터를 읽을려고 시도하면 EOF를 리턴한다.
반대로 데이터를 쓰려고 할 경우, 해당 프로그램은 SIGPIPE 시그널을 받게되고,
시스템 호출은 EPIPE로 실패한다. 시그널 핸들러가 없는 경우 errno를 확인하는 것으로 에러처리하는 것이 바람직하다.
7. close() 시스템 함수
연결된 socket를 닫을 때 사용한다.
8. 연결형 서버-클라이언트 흐름도
'System Program > socket' 카테고리의 다른 글
IP주소 및 포트 정보관련 시스템 함수 (0) | 2014.03.04 |
---|---|
IP주소 및 포트 관리 (0) | 2014.03.04 |
주소 구조체 (0) | 2014.03.04 |
호스트,네트워크간 변환 함수 정리 (0) | 2014.03.04 |
기본 소켓시스템 함수 (비연결형) (0) | 2014.03.03 |