Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

codingfarm

4. 소켓 네트워크 프로그램 개발 - 3. 소켓 설정(bind 함수) 본문

TCP IP 소켓 프로그래밍

4. 소켓 네트워크 프로그램 개발 - 3. 소켓 설정(bind 함수)

scarecrow1992 2021. 5. 10. 22:37

학습 목표

  • bind 함수로 소켓을 설정하는 방법을 배운다

 

socket 함수로 특정 도메인과 타입, 프로토콜에 맞는 소켓을 생성하고 나면, bind 함수로 소켓에 IP와 포트를 할당한다.

  • server : bind 함수를 통해 소켓에 IP와 포트를 할당함
  • client : 연결할 인터넷 서비스(server)의 포트만 알면 됨 (자신의 포트는 몰라도 됨)

 

bind 함수의 원형

int bind( SOCKET sockfd, const sockaddr *my_addr, int namelen );
cs

 

함수의 매개변수

  • sockfd : 앞서 socket 함수로 생성된 endpoint 소켓의 식별 번호
  • my_addr : IP 주소와 port 번호를 저장하기 위한 변수가 있는 구조체
  • namelen : 두 번째 인자의 데이터 크기
  • 반환값 : 성공하면 0, 실패하면 -1

 

2번째 매개변수에는 sockaddr이 아닌 다양한 종류의 구조체 변수가 전달된다. 소켓에는 여러 유형이 있는 만큼 설정하는 방법도 다양하므로 설정을 위한 다양한 구조체 타입이 존재한다. 그러므로 bind 함수에서는 type casting하여 타입을 넘겨줘야 한다. 다만 컴퓨터는 해당 매개변수의 크기를 알 수 없으므로 3번째 매개변수를 통해 2번째 입력된 데이터의 크기를 전달해야한다.

널리 쓰이는 IPv4 도메인에서 통신하기 위한 소켓을 bind 할때는 sockaddr_in 타입이 주로 쓰이며 내부 통신용 소켓의 bind에는 sockaddr_in이 쓰인다. 각 구조체의 원형은 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct sockaddr {
   unsigned short  sa_family;    
   char    sa_data[14];
};
 
struct sockaddr_in {
   short   sin_family;
   unsigned short sin_port;
   struct  in_addr sin_addr;
   char    sin_zero[8];
};
 
struct sockaddr_un {
    unsigned short sin_family;
    char sun_path[108;
};
cs

위 구조체를 보면 sa_family와 sin_family의 타입이 똑같은것을 볼 수 있는데,  이 변수값을 통해 bind 함수가 전달받은 소켓의 종류를 알 수 있다.

 

bind 함수는 대략 아래와 같은 방법으로 어떤 소켓 구조체인지 확인해서 코드를 분기한다.

 

사용 예

1
2
3
4
5
6
7
8
9
10
11
12
struct sockaddr_in clientaddr, serveraddr, myaddr;
 
memset(&serveraddr, 0x00sizeof(serveraddr));    // 사용전에 초기화
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); // 모든 주소에서 받겠다(0.0.0.0)
serveraddr.sin_port = htons(12345);
 
state = bind(sockfd, (struct sockaddr *&serveraddr, sizeof(serveraddr));
if (state == -1) {
    perror("bind error : ");
    exit(0);
}
cs

1번 줄 : sockaddr_in 타입의 구조체 변수를 3개 만드는데 bind 함수에선 serveraddr만 사용한다. 

3번 줄 : serveraddr을 사용하기 전에 memser함수를 사용하여 초기화한다. memset 대신 무조건 0x00으로 초기화 하는 bzero를 써도 되지만, 가급적 ANSI C 표준인 memset을 사용한다

앞서 bind 함수의 원형을 보면 2번째 매개변수가 sockaddr 이었는데, 8번째 줄을보면 sockaddr_in 타입 구조체 변수의 포인터를 전달한다. 대신 sockaddr * 으로 타입 캐스팅 하는것을 볼 수 있다.

 

5번, 6번줄에서 htonlhtons 라는 함수가 쓰였다

2개의 함수 모드 , Host System의 Byte Order에 맞게 데이터를 변환해 주기 위해 사용된다.

codingfarm.tistory.com/540?category=812608

ehpub.co.kr/tag/htonl-%ED%95%A8%EC%88%98/

 

Comments