반응형

작성 절차

 

 

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);	// 연결을 기다리는 클라이언트의 회대 수

 

  1. 클라이언트가 listen()을 호출해 둔 서버 소켓을 목적지로 connect()를 호출
  2. 3-Way Handshake 연결설정을 시작
  3. 커널(시스템)이 Handshake를 마친 후
  4. 서버 어플리케이션이 설정된 연결을 받아들이는 과정이 필요
  5. 이를 위해 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 연결동작과 함수들의 동작

  1. 클라이언트 Application > connect()
  2. 클라이언트 Kernel > SYN(x) 전송
  3. 서버 Kernel > ACK(x+1), SYN(y) 응답
  4. 클라이언트 Kernel > ACK(y+1) 전송
  5. 3-Way Handshake() 완성
    1. 클라이언트의 connect() 리턴 x, Kernel 사이 Handshake만 완료한 상태
    2. 서버 Application이 listen()을 하지 않았더라면 과정 3은 안 일어남, RST 패킷 전송
      > Error : Connect Refused 리턴
  6. 서버 Kernel > 해당 소켓의 accept 큐에 이 연결을 전달
  7. 서버 Application > accept()를 호출
  8. 서버 > accept 큐에서 하나의 연결(Handshake 완료된 연결)을 꺼내감
  9. 클라이언트 > connect() 리턴
  10. 데이터 송수신 가능
반응형