본문 바로가기

리눅스 소켓 프로그래밍 TCPIP

UDP 서버 - 클라이언트

TCP와 UDP 차이점

 

 

 

 

UDP 서버

1. socket( ) 함수로 소켓을 생성함으로써 사용할 프로토콜 결정

2. bind( ) 함수로 지역 IP 주소와 포트번호를 결정

3. 클라이언트가 보낸 데이터를 recvfrom( ) 함수로 받음

     -> 이 때 원격 IP주소와 포트번호를 알 수 있음

4. 받은 데이터를 처리해 sendto( ) 함수로 보냄

5. 작업을 마치면 close( ) 로 소켓을 닫음

 

UDP 클라이언트

1. socket( ) 함수로 소켓을 생성함으로써 사용할 프로토콜 결정

2. sendto( ) 함수로 서버에 데이터를 보냄

    -> 이 때 원격 IP주소와 원격포트번호, 지역 IP주소와 포트번호가 결정됨

3. 서버가 처리해 보낸 데이터를 recvfrom( ) 함수로 받음

4. 모든 작업을 마치면 close( ) 로 소켓을 닫음

 

 

sendto( ) 함수

  • 응용 프로그램 데이터를 운영체제의 송신 버퍼에 복사함으로 데이터 전송
  • 함수 호출 시 지역 IP주소와 지역포트번호가 아직 결정되지 않은 상태라면 운영체제가 자동으로 결정
    -> 즉 sendto( ) 함수가 TCP의 bind( ) 함수 역할까지 대신 해줌
C

#include <sys/types.h>
#include <socket.h>

ssize_t sendto(
                ① int sock
                ② void *buf
                ③ size_t len
                ④ int flags
                ⑤ struct sockaddr *addr
                ⑥ socklen_t addrlen
);

1. 통신에 사용할 소켓
2. 보낼 데이터를 담고 있는 응용 프로그램 버퍼의 주소
3 보낼 데이터의 크기
4. sendto( ) 함수의 동작을 바꾸는 옵션 대부분 0
5. 목적지 주소를 담고 있는 소켓 주소 구조체 
 -> UDP의 경우 특정 호스트나 라우터 주소, 브로드캐스트,멀티캐스트 주소를 사용할 수 있음
6 목적지 주소를 담고 있는 소켓 주소 구조체의 크기 (바이트)

 

 

recvfrom( ) 함수

  • 운영체제의 수신 버퍼에 도착한 데이터를 응용 프로그램 버퍼에 복사한다.
  • TCP와 다른점은 UDP 패킷 데이터를 한 번에 하나만 읽을 수 있다는 점이다.
     -> 응용 프로그램이 큰 버퍼를 준비해도 많은 데이터를 한꺼번에 읽을 수 없다.

 

C

#include <sys/types.h>
#include <socket.h>

ssize_t recvfrom(
                ① int sock
                ② void *buf
                ③ size_t len
                ④ int flags
                ⑤ struct sockaddr *addr
                ⑥ socklen_t *addrlen
);

1. 통신에 사용할 소켓
    -> sendto( ) 함수의 소켓과 달리 반드시 지역주소가 미리 결정되어있어야함
2. 받은 데이터를 저장할 응용 프로그램 버퍼의 주소
3. 응용 프로그램 버퍼의 크기
4. recvfrom( ) 함수의 동작을 바꾸는 옵션 대부분 0
5. 소켓 주소 구조체를 전달하면 송신자의 주소 정보로 채워짐
6. 정수형 변수를 addr이 가리키는 소켓 주소 구조체의 크기로 초기화 후 전달
    -> recvfrom( ) 함수가 리턴하면 *addrlen 변수는 함수가 채워넣은 주소의 크기를 갖게된다.

 

 

브로드캐스팅

TCP와 구별되는 UDP의 특징은 브로드캐스팅과 멀티캐스팅이다.

 

유니캐스팅 : 한 개체가 다른 한 개체에 데이터를 보내는 모델 (IPv4, IPv6)

 

브로드캐스팅 : 한 개체가 특정 네트워크에 속한 모든 개체에 데이터를 보내는 모델 (IPv4)

 

멀티캐스팅 : 동일 그룹에 가입한 모든 개체에 데이터를 보내는 모델 (IPv4, IPv6)

                      -> 개념적으로 브로드캐스팅은 멀티캐스팅의 특수한 경우로 볼 수 있다.

 

애니캐스팅 : 한 개체가 동일 그룹에 가입한 개체 중 가장 가까운 하나에만 데이터를 보내면,
                     데이터를 받은 개체가 그룹에 속한 나머지 개체에 데이터를 보내는 모델 (IPv6)

 

 

 

브로드캐스팅 개념

  • 송신자가 보낸 데이터 하나를 다수의 수신자가 받는 방식
  • 데이터 복사본을 여러 개 만들어 보내는 것이 아님
     -> 송신자 관점에서 보면 상당히 효율적임

 

데이터를 받는 쪽에서는 프로토콜과 포트번호만 일치시키면 된다.

 

소켓 응용 프로그램에서 브로드캐스트 데이터를 보내려면 절차가 필요하다.

 

1. 브로드캐스팅을 활성화한다.

 

int bEnable = 1;
retval = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bEable, sizeof(bEnable));

 

socket( ) 함수로 생성한 소켓은 기본적으로 유니캐스팅만 가능

setsockopt( ) 함수

첫번 째 인수 : 소켓

두번 째 인수 : SOL_SOCKET

세번 째 인수 : SO_BROADCAST

이 상태에서

네 번째 인수 :  0이 아닌 값을 담은 변수의 주소값 을 전달하면
                       해당 소켓에 대한 브로드캐스팅이 활성화 되고 데이터를 보낼 수 있다.

 

2. 브로드캐스트 주소를 목적지로 설정하여 데이터를 보낸다

 

 

// 소켓 주소 구조체 초기화
struct sockaddr_in remoteaddr; // 송신할 대상 주소 정보를 저장하는 구조체
memset(&remoteaddr, 0, sizeof(remoteaddr)); // 구조체를 0으로 초기화하여 불필요한 값 제거

remoteaddr.sin_family = AF_INET; // 주소 체계를 IPv4로 설정
inet_pton(AF_INET, "255.255.255.255", &remoteaddr.sin_addr); 
// 브로드캐스트 주소("255.255.255.255")를 네트워크 바이트 순서로 변환하여 구조체에 저장
remoteaddr.sin_port = htons(9000); 
// 포트 번호 9000을 네트워크 바이트 순서(big-endian)로 변환 후 저장

// 송신용 버퍼를 선언하고 데이터 넣기
char buf[BUFSIZE]; // 송신할 데이터를 저장할 버퍼 선언
// ... (여기서 buf에 전송할 데이터를 채워 넣어야 함)

// sendto() 함수로 데이터 보냄
retval = sendto(sock, buf, (int)strlen(buf), 0, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr));
// sock: 송신용 소켓 디스크립터
// buf: 송신할 데이터를 가리키는 포인터
// (int)strlen(buf): 송신할 데이터의 크기(바이트 단위)
// 0: 추가 옵션 플래그 (일반적으로 0으로 설정)
// (struct sockaddr *)&remoteaddr: 송신 대상의 주소 정보
// sizeof(remoteaddr): 주소 정보의 크기

if (retval == SOCKET_ERROR) {
    // 오류처리: sendto 함수가 실패하면 SOCKET_ERROR 반환
    perror("sendto 실패"); // 오류 메시지를 출력
    exit(EXIT_FAILURE);    // 프로그램 종료
}

// 성공적으로 데이터가 전송된 경우
printf("%d바이트를 보냈습니다\n", retval);
// 실제로 전송된 바이트 수를 출력

 

브로드캐스트 종류

 

IPv4 주소는 크게 네트워크 ID 와 호스트 ID 로 나눌 수 있다

서브넷을 사용하는 경우 호스트 ID일부는 서브넷ID 로 사용된다.

브로드캐스팅용으로 예약된 IPv4 주소는 그림과 같은 구조를 가짐

 

 

 

  • 네트워크 브로드 캐스트
    호스트 ID 비트가 모두 1인 경우
    특정 네트워크에 대한 브로드 캐스팅을 의미
    브로드캐스트가 라우터를 거쳐야 하므로 라우터 설정에 따라 불가능
    실용적 주소로 사용하기 어려움


  • 서브넷 브로드캐스트
    서브넷 ID를 제외한 호스트ID 비트가 모두 1인경우
    특정 서브넷에 대한 브로드캐스팅을 의미
    라우터를 통과하지 못할 수 있음
    자신이 속한 서브넷에 대한 브로드캐스팅은 가능

  • 지역 브로드캐스트
    네트워크 ID 와 호스트ID 비트가 1인경우 (IPv4 주소 255.255.255.255)
    송신자 자신이 속한 네트워크에 대한 브로드캐스팅
    항상 브로드캐스팅이 가능
    데이터가 라우터 경계를 넘어가지 않음
    대부분 지역 브로드캐스트 사용

 

'리눅스 소켓 프로그래밍 TCPIP' 카테고리의 다른 글

소켓 입출력 모델 Select, Poll, EPoll  (3) 2024.12.18
소켓 옵션  (0) 2024.12.17
멀티 스레드 : 리눅스  (3) 2024.12.16
TCP 서버 - 클라이언트  (1) 2024.12.13
소켓 주소 구조체 다루기  (3) 2024.12.13