written by yechoi

[TCP/IP] 프로토콜 주소 정보 담기 본문

Born 2 Code/C, C++

[TCP/IP] 프로토콜 주소 정보 담기

yechoi 2021. 1. 7. 11:24
반응형

단일 접속 서버 구현하기

두 개의 컴퓨터에 있는 프로세스간 통신

  • 각각의 컴퓨터는 send buffer, receive buffer (socket) 모두 생성
  • 인터넷을 통해 통신

 

 

프로토콜 주소 정보 담기

struct sockaddr_in 에 정보를 담을 것. 구조체의 구성은 다음과 같음.

  • sin_family (4byte) : 프로토콜 유형, IPv4의 경우 AF_INET로 기입
  • sin_port (4byte) : 포트번호(네트워크 방식의2진)
  • sin_addr.s_addr (8byte) : ip 주소(2진)
  • 안쓰는 8byte

 

 

포트번호 변환

네트워크 바이트 순서인 빅엔디안으로 2진법으로 표현해야 함.호스트 바이트 순서는 machine-dependent(빅엔디안/리틀엔디안)하므로, 이를 네트워크 바이트로 그대로 쓰면 안된다.

  • 호스트 바이트 순서 -> 네트워크 바이트 순서 변환
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • 네트워크 바이트 순서 -> 호스트 바이트 순서 변환
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

 

 

IP 주소 변환

IP 주소는 다음과 같은 세가지 방식으로 표현할 수 있다.

  1. 도메인 문자열 www.google.com
  2. 10진수 문자열 192.128.0.1
  3. 이진수 0xcbf92703

 

우리가 구조체에 담을 값은 3번 이진수 IP다.

  • 10진수 문자열 -> 이진수
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
  • 이진수 -> 10진수 문자열
char *inet_ntoa(struct in_addr in);
  • 도메인 -> 이진수
#include <netdb.h>
extern int h_errno;

struct hostent *gethostbyname(const char *name);
  • 이진수 -> 도메인
#include <sys/socket.h>       /* for AF_INET */
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);

 

c.f . struct hostent

       The hostent structure is defined in <netdb.h> as follows:

           struct hostent {
               char  *h_name;            /* official name of host */
               char **h_aliases;         /* alias list */
               int    h_addrtype;        /* host address type */
               int    h_length;          /* length of address */
               char **h_addr_list;       /* list of addresses */
           }
           #define h_addr h_addr_list[0] /* for backward compatibility */

 

 

코드

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(void)
{
  int                                    tcpSd;
  struct sockaddr_in    s_addr;

  if ((tcpSd = socket(PF_INET, SOCK_STREAM, 0)) < 0) // TCP 소켓 만들기
  {
    perror("socket()");
    exit(-1);
  }

  bzero((char*)&s_addr, sizeof(s_addr));
  s_addr.sin_faimily = AF_INET;
  inet_aton("203.249.39.3", &s_addr.sin_addr.s_addr); // IP번호 이진수로 변환
  s_addr.sin_port = htons(7); // 포트번호를 네트워크 바이트 순서로 변환

  print("ip(dotted decial) = %s\n", inet_ntoa(addr.sin_addr.s_addr)); //IP주소 도메인으로 변환
  print("ip(binary) = %x\n", ntohl(s_addr.sin_addr.s_addr)); // 호스트 방식의 이진 IP 주소
  print("port no = %d\n", ntohs(s_addr.sin_port)); // 호스트 방식의 포트 번호

  closd(tcpSd);
}
반응형