'inet_addr()'에 해당되는 글 1건

  1. 2009.12.15 bind()
2009. 12. 15. 10:30

bind()



통신을 위한 소켓을 생성하고나면, 소켓에 주소를 할당해야 한다. 이때 사용하는 함수가 'bind()' 이다.

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

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);

  • sockfd - 주소를 할당하고자 하는 소켓의 파일 디스크립터
  • myaddr - 할당하고자 하는 주소정보를 가지고 있는 구조체 변수의 포인터
  • addrlen - 인자로 전달되는 주소정보 구조체의 길이
  • 리턴값 - 성공 시 0, 실패 시 -1 을 리턴

두 번째 인자 myaddr는 struct sockaddr* 형이지만, 실제는 sockaddr_in을 형변환 한 것이다.
sockaddr_in을 살펴보면...

struct sockaddr_in {
    sa_family_t     sin_family;        // 소켓 타입
    uint16_t           sin_port;          // 연결에 사용되는 포트 번호
    struct in_addr  sin_addr;         // 연결을 받아들일 주소
    char               sin_zero[8];    // 사용되지 않음
}

struct in_addr {
    uint32_t    s_addr;                  // IPv4 인터넷 주소
}


소켓 생성을 해서 소켓에 주소를 할당하는 bind() 까지의 예

...   
int serv_sock;
char *serv_ip = "127.0.0.1";
char *serv_port = "9190";
struct sockaddr_in serv_addr;

serv_sock = socket(PF_INET, SOCK_STREAM, 0);        /* 소켓 생성 */
if(serv_sock == -1)
// error 처리..
 
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;                               // 소켓 타입
serv_addr.sin_addr.s_addr = inet_addr(serv_ip);         // IP 주소
serv_addr.sin_port = htons(atoi(serv_port));               // 포트 번호 

if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)     /* 소켓에 주소 할당 */
// error 처리..
...


추가 #1.
소켓에 사용되는 모든 데이터는 Big Endian으로 동작한다. 일반적으로 사용하는 기계가 Little Endian 인경우가 대부분이고, 혹시나 모르기 때문에 소켓에 사용되는 데이터(IP 주소, 포트 번호 등)은 네트워크 바이트 순서(Big Endian)으로 변경해 주어야 한다.
이 때 사용되는 함수가 htons(), ntohs(), htonl(), ntohl() 이다.
h - host byte
n - network byte
l - long (32bit)
s - short (16bir)
htons()라고 한다면 short형의 host byte를 short형의 network byte로 변경해준다는 의미이다.
[참고] Endian에 대해서는 이곳을 참고!!!

추가 #2.
IP 주소를 보면 127.0.0.1 과 같은 형태인 것을 볼 수 있다. 하지만 실제 사용될 때에는 unsigned long 형으로 표현이 된다.
127.0.0.1 과 같은 형태를 'Dotted-Decimal Notation'이라고 부르며, 이는 위의 예제 소스에서 확인 할 수 있듯 문자열이다. 이를 unsigned long 형으로 바꾸어주는 함수가 'inet_addr()' 이다.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

unsigned long inet_addr (const char* string);


추가 #3.
위의 예제 소스를 보면 IP 주소를 직접 입력했다. 하지만 직접 IP 주소를 입력할 경우 다른 기계에서 동작을 할 수 없게 된다. 각 기계마다 IP 주소가 동일한 것이 아니기에...
이 때 'INADDR_ANY' 라는 상수를 통해서 현재 시스템의 IP를 자동으로 찾아서 할당해 주는 방법을 사용할 수 있다.

...   
char *serv_port = "9190";
struct sockaddr_in serv_addr;
...
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;                                         // 소켓 타입
serv_addr.sin_addr.s_addr = inet_addr(INADDR_ANY);         // IP 주소
serv_addr.sin_port = htons(atoi(serv_port));                          // 포트 번호 
...


 

'Programmings > TCP/IP socket programming' 카테고리의 다른 글

connect()  (0) 2009.12.18
listen() and accept()  (0) 2009.12.16
socket()  (0) 2009.12.15