- 인터넷 주소
> IPv4(Internet Protocol version 4) : 4바이트 주소체계
> IPv6(Internet Protocol version 6) : 16바이트 주소체계
- IPv4 = 네트워크ID + 호스트ID
https://ko.wikipedia.org/wiki/IPv4
- 네트워크 주소 : 네트워크 구분을 위한 IP 주소 일부
데이터 전송은 먼저 IP주소중 네트워크 주소만 참조해서 해당 네트워크에 전송한 다음 네트워크를 구성하는 라우터를 거쳐 남은 호스트 주소를 참조하여 해당 IP 주소의 컴퓨터로 전송됨
cf. 라우터와 스위치
외부로부터 수신된 데이터를 호스트에 전달하고 호스트가 전달하는 데이터를 외부로 송신해주는 물리적 장치. 라우터보다 기능적으로 작은 것을 스위치라 함
- 첫 번째 바이트로 네트워크 주소가 몇 바이트인지(네트워크 ID 바이트 크기 -> 클래스) 판단 가능
클래스 A : 0~127 클래스 B : 128~191 클래스 C : 192~223
=> 클래스 A 첫 번째 비트 : 0 클래스 B 첫 번째 비트 : 10 클래스 C의 첫 번째 비트 : 110
- PORT 번호
> IP는 컴퓨터 구분 목적
> IP는 NIC(Network Interface Card)를 통해 컴퓨터 내부로 전송
> 컴퓨터 내부에서 OS가 PORT 번호를 활용하여 소켓을 적절히 분배함.
> PORT 번호는 OS 내에서 소켓을 구분하는 목적 => 한 OS 내에서 같은 PORT번호 중복 불가
> 16비트 => 0~65535, 0부터 1023까지는 Well-known Port라 해서 특정 프로그램에 이미 할당됨
> PORT 번호는 중복이 불가능 하지만
TCP소켓과 UDP소켓은 PORT번호를 공유하지 않기 때문에 중복이 가능
- SOCKADDR_IN 구조체 : bind 함수 주소 정보 전달 용도
typedef struct sockaddr_in
{
sa_family_t sin_family; // 주소체계
uint16_t sin_port; // 16비트 TCP/UDP PORT 번호
struct in_addr sin_addr; // 32비트 IP주소
char sin_zero[8]; // 사용안함
} SOCKADDR_IN;
typedef stuct in_addr
{
in_addr_t s_addr; // 32비트 IPv4 인터넷 주소
} IN_ADDR;
cf.
sa_family_t 주소 체계
socklen_t 길이 정보
in_addr_t IP 주소 정보, uint32_t
in_port_t PORT번호정보, uint16_t
> 멤버 sin_familty
AF_INET IPv4 인터넷 프로토콜에 적용하는 주소체계
AF_INET6 IPv6 인터넷 프로토콜에 적용하는 주소체계
AF_LOCAL 로컬 통신을 위한 유닉스 프로토콜의 주소체계
> 멤버 sin_port
16 비트 PORT 번호, 네트워크 바이트 순서(빅 엔디안)로 저장
htons() 함수 이용 (host to network short)
> 멤버 sin_addr
32 비트 IP주소 정보, 네트워크 바이트 순서(빅 엔디안)로 저장
htonl() 함수 이용 (host to network long)
> 멤버 sin_zero
의미 없음, sockaddr_in의 크기를 sockaddr과 일치 시키기 위한 멤버
- sockaddr 구조체를 사용하기엔 불편하게 되어있고 요구사항이 까다로워서 sockaddr_in을 사용하고
형변환을 함.
typedef struct sockaddr
{
sa_family_t sin_family; // 주소 체계 (Address Family)
char sa_data[14]; // 주소 정보
} SOCKADDR;
- 엔디안
> 빅 엔디안 : 낮은 번지 부터 높은 자리 순 (Network Byte Order) ex) 0x12345678 -> 0x12345678
> 리들 엔디안 : 낮은 번지 부터 낮은 자리 순 (Host Byte Order) ex) 0x12345678 -> 0x78563412
> 바이트 순서 변환 함수
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long htonl(usigned long);
> intel, AMD는 리틀 엔디안 이라서 변환 함
> 빅 엔디안일 경우 함수를 사용해도 변환 안함
- IP 주소 함수
in_addr_t inet_addr(const char* string); // 성공 : 빅 엔디안으로 변환된 32비트 값, 실패 : INADDR_NONE
: IP주소 문자열을 네트웨크 바이트 순서로 32비트 정수형으로 동시에 변환
* error C4996 오류남
=>
#include <Ws2tcpip.h>
#define InetPton inet_pton
INT inet_pton(INT Family, // AF_INET : IPv4, AF_INET6 : IPv6
PCSTR pszAddrString, // Dotted-Decimal Notation 주소 문자열 주소
PVOID pAddrBuf // IPv4는 IN_ADDR, IPv6는 IN6_ADDR (변환된 주소 저장됨)
); // 비스타 이상부터 호환
: IPv4와 IPv6 모두 지원(맨 앞 Family로 구분)
#include <arpa/inet.h> // 리눅스
int inet_aton(const char* string, struct in_addr* addr); // 성공 : 1(true), 실패 : 0(false)
: inet_addr() 과 역할은 같으며 구조체 변수 in_addr을 이용함
#include <arpa/inet.h> // 리눅스
char* inet_ntoa(struct in_addr adr); // 성공 : 변환된 문자열 주소, 실패 : -1
: 네트워크 바이트 순서로 정렬된 정수형 IP주소 정보를 보기 쉬운 문자열로 변환함
cf. INADDR_ANY : 동작하는 컴퓨터의 IP주소
> 컴퓨터 내에 두 개 이상의 IP를 할당 받아서 사용할 경우(Multi-homed, 라우터가 해당)
할당 받은 IP 중 어떤 주소를 통해서 데이터가 들어오더라도 PORT 번호만 일치하면 수신할 수 있음
> 서버 프로그래밍에는 선호
> 클라 프로그래밍에서는 서버 기능이 포함 되지 않는 이상 잘 사용 안함
- 소켓에 인터넷 주소 할당하기
int bind(
SOCKET s, // 주소 정보(IP, PORT)를 할당할 핸들
struct sockaddr* myaddr, // 할당하고자 하는 주소 정보를 지니는 구조체 변수 주소 값
socklen_t addrlen // 두 번째 인자의 길이
); // 성공 : 0, 실패 : SOCKET_ERROR
ex)
SOCKET servSock;
SOCKADDR_IN serv_addr;
char* serv_port = "9190"
// 서버 소켓 (리스팅 소켓) 생성
servSock = socket(PF_INET, SOCK_STREAM, 0);
// 주소 정보 초기화
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; // inet_addr(), inet_aton() 사용 가능
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(serv_port));
// 주소 정보 할당
bind(servSock, (SOCKADDR*) &serv_addr, sizeof(serv_addr));
cf. winsock2의 다양한 프로토콜 적용 가능한 변환 함수
INT WSAStringToAddress(
LPSTR AddressString, // IP와 PORT번호 담고있는 문자열
INT AddressFamily, // 주소 체계
LPWSAPROTOCOL_INFO lpProtocolInfo, // 프로토콜 Provider 설정, 일반적으로 NULL
LPSOCKADDR lpAddress, // 주소정보 담을 구조체 변수 주소
LPINT lpAddressLength // 네번째 인자 크기
); // 성공 : 0, 실패 : SOCKET_ERROR
INT WSAAddressToString(
LPSOCKADDR lpsaAddress, // 문자열로 변환할 주소정보 지닌 구조체 변수 주소
DWORD dwAddressLength, // 첫번째 인자 크기
LPWSAPROTOCOL_INFO lpProtocolInfo, // 프로토콜 Provider 설정, 일반적으로 NULL
LPTSTR lpszAddressString, // 문자열로 변환된 결과를 저장할 배열의 주소
LPDWORD lpdwAddressStringLength // 네번째 인자 배열 크기를 담는 변수 주소
); // 성공 : 0, 실패 : SOCKET_ERROR
'programing > Networks' 카테고리의 다른 글
Half-close, DNS, 소켓 옵션 (0) | 2015.05.15 |
---|---|
UDP 기반 서버 / 클라 (0) | 2015.05.14 |
TCP 기반 서버 / 클라 (0) | 2015.05.13 |
소켓 프로그래밍 기본 함수 및 소켓과 프로토콜 (0) | 2015.05.12 |
[펌] BeeJ's Guide to Network Programming (0) | 2015.05.04 |