반응형
작성 절차
socket() : 소켓 생성
서버도 클라이언트와 통신하기 위해서는 소켓을 만들어야 합니다. 사용법은 클라이언트와 같습니다.
// 소켓 생성
socket(PF_INET, SOCK_STREAM, 0);
bind()
생성된 소켓에 응용 프로그램만 알고 있는 이 소켓 번호와 소켓의 주소(IP 주소 + Port 번호)를 연결해 줍니다.
bind()는 성공 시 0, 실패 시 -1을 리턴합니다.
// 소켓 생성
s = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in servaddr;
// 소켓주소 구조체 내용
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "203.252.65.3", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
/* 자동으로 자신 IP 쓰는 법
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
*/
// 소켓번호와 소켓주소를 bind
bind(s, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen()
- 능동적 소켓 : 클라이언트의 TCP 소켓, 서버에 연결 요청
- 수동적 소켓 : 서버의 TCP 소켓, 연결 요청 받아들이기
socket() 함수에 의해 생성된 소켓 = 능동적 소켓 > 수동적 소켓으로 변경해야 함 = listen() 호출
// listen() 사용 문법
int listen (
int s, // 소켓 번호
int backlog); // 연결을 기다리는 클라이언트의 회대 수
- 클라이언트가 listen()을 호출해 둔 서버 소켓을 목적지로 connect()를 호출
- 3-Way Handshake 연결설정을 시작
- 커널(시스템)이 Handshake를 마친 후
- 서버 어플리케이션이 설정된 연결을 받아들이는 과정이 필요
- 이를 위해 accept()가 사용됩니다.
- 1인 출입 가게 = accept() : accept()는 한 번에 하나의 연결만을 가져감
- 대기줄 = accept큐 : 나머지 연결들 대기시켰다가 accept()가 부를 때마다 accept큐에서 보내
- listen()의 backlog = accept큐의 크기(대기시켜놓을 수 있는 크기)
- 대기 중인 연결들 = 3-Way Handshake를 마친 연결들
- backlog에 의존하면 안 됨
- 다른 유닉스 시스템에서는 backlog 값이 현재 3-Way Handshake의 과정에 있는 연결 요청의 수만 나타내기도 하고, Handshake를 마친 요청과 연결 과정 중에 있는 요청을 합한 수를 나타내기도 하기 때문
성공 시 0, 실패 시 -1 리턴
// listen() 사용 예시
listen(s ,2);
// 능동>수동 모드로 바꿔주기만 하기 때문에 즉시 리턴됨
accept()
// accept() 사용 문법
int accept (
int s, // 소켓 번호
struct sockaddr *addr, // 연결 요청을 한 클라이언트의 소켓주소 구조체
int *addrlen); // *addr 구조체의 크기의 포인터
accept() 성공 시 소켓 새로 생성(클라이언트와의 통신에 사용), 실패 시 -1 리턴
3-Way Handshake 연결동작과 함수들의 동작
- 클라이언트 Application > connect()
- 클라이언트 Kernel > SYN(x) 전송
- 서버 Kernel > ACK(x+1), SYN(y) 응답
- 클라이언트 Kernel > ACK(y+1) 전송
- 3-Way Handshake() 완성
- 클라이언트의 connect() 리턴 x, Kernel 사이 Handshake만 완료한 상태
- 서버 Application이 listen()을 하지 않았더라면 과정 3은 안 일어남, RST 패킷 전송
> Error : Connect Refused 리턴
- 서버 Kernel > 해당 소켓의 accept 큐에 이 연결을 전달
- 서버 Application > accept()를 호출
- 서버 > accept 큐에서 하나의 연결(Handshake 완료된 연결)을 꺼내감
- 클라이언트 > connect() 리턴
- 데이터 송수신 가능
반응형