Transcript socket3

TCP/IP 소켓 프로그래밍 3장
Linux에서의
IP, Port, 네트워크 바이트 순서, 주소 변환
주소 할당 등…
IP
 인터넷상에 존재하는 호스트들을 구분하기
위한 32비트 주소 체계를 의미한다.
 Dotted-decimal Notation을 사용한다.
 (ex : 165.132.141.174 – 공학원 그곳의 주소)
 한마디로 집주소랑 비슷하다고 보면 된다.
Port의 필요성
 IP만 가지고는 통신하는데 한계가 크다.
 예를 들어 우리 집에 누군가가 나에게 편지
를 보냈는데 집주소만 적혀 있다고 치자.
그러면 그 편지는 누가 읽어야 할 것인가?
 이런 문제를 해결하는 것이 Port다.
Port의 필요성
 한 컴퓨터 내에서도 다양한 프로그램들이 인터넷
을 통해 외부와 소통하고 있다.
 예를 들어 msn과 NateOn을 켜고 Internet
Explorer로 자료를 찾는다고 치자.
 그럼 IP주소로 온 수많은 데이터는 세 프로그램 중
에 어디로 가야 할까?
 이것을 정해주는 것이 Port 이다.
Port
 Port는 16bit로 주소를 표현한다. 즉 2byte
 그럼 포트의 주소 범위는 자연스럽게 정해
진다. 2^16 개의 주소를 가질 수 있다.
 0~65535번 까지 인데 0부터 1023번 까지
는 잘 알려진 Port라고 해서 이미 쓰이므로
왠만해서는 다른 포트를 쓰길 바란다.
Port
 당연한 이야기지만 하나의 포트로 여러 개
의 프로그램이 동시에 못쓴다.
 하지만 TCP 소켓과 UDP 소켓은 Port를
서로 공유하지 않으므로 중복되어도 됨
 결론 : 데이터 전송을 위해서는 IP와 Port가
필요함!
IPv4 주소체계를 나타내는 구조체
 알아두면 주소할당 할 때 소스 보기 편함
 uint16_t는 unsinged 16-bit int 입니다

sa_family_t sin_family;
 프로토콜 체계마다 주소 체계가 다른다.
 sin_family에는 주소체계에 대한 정보가 들어간
다.
•
•
•
AF_INET : IPv4 인터넷 프로토콜
AF_INET6 : IPv6 인터넷 프로토콜
AF_LOCA : Local 통신을 위한 UNIX 프로토콜


책에 이 변수에 관한 부가적 설명을 읽는게 좋음
PE_INET와 AF_INET가 헷깔리지 않는가?? ㅋㅋ
Big-Endian과 Little-Endian
 모르겠음… -_-;;
 그냥 메모리 읽는 방식이 서로 반대라는 것
 인텔 계열은 Little-Endian 쓴다.
 네트워크 표준은 Big-Endian
 네트워크로 데이터 보낼 때 Big-Endian으로 바꿔야 함.
 그런데 왜 주소 데이터만 바꾸는지 모르음 -_-;;;
변환 함수들
 함수이름이 외우기 좋게 약자로 되어 있다.
•
•
•
•
h : host byte order
n : network byte order
s : short (16bit)
l : long (32bit)
변환 함수들
 unsigned short htons(unsigned short);
 unsigned short 데이터가
 host byte 순서(Little-Endian 방식)에서
network byte 순서(Bing-endia 방식)으로
바뀐다는 함수
• 보통 port를 바꿀 때 쓰겠지?
변환함수들 정리
 모두 정리하면
•
•
•
•
unsigned
unsigned
unsigned
unsigned
short htons(unsigned short);
short ntohs(unsigned short);
long htonl(unsigned long);
long ntohl(unsigned long);
 각각의 쓰임새를 생각 해 보는 것도 좋음
위의 함수들의 문제!
 포트는 몰라도 IP주소는 일명
‘점박이 삼형제’ 때문에 도저히
쓸 수가 없다 -_-;
 그래서 다른 함수들을 쓴다.
inet_addr()
 IP주소를 바로 32bit Big-Endian으로 바꿔줌

•
•
•
필요한 헤더파일
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 unsigned long inet_addr(const char *string);
 성공 시 32bit Big-Endian 32비트 값
 오류시 INADDR_NONE 리턴
inet_aton()
 inet_addr()과 같은 기능
 필요한 헤더파일도 같음
 단지 조금 편한 점이 잇음
 int inet_aton(const char *string, struct in_addr *addr);
 인자를 보면 바꾼 주소를 대입 할 변수의 포인터
도 있다. 즉 앞의 함수와 달리 호출 하기만 하면
된다.
Inet_ntoa()
 32bit Big-Endian을 바로 IP로 바꿔줌

•
•
•
필요한 헤더파일
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 char *inet_ntoa(struct in_addr addr);
 성공 시 변환된 해당 문자열의 포인터를 리턴
 실패 시 -1 리턴
인터넷 주소 초기화
bind()로 소켓에 주소 할당하기
 필요한 헤더파일
• #include <sys/type.h>
• #include <sys/socket.h>
 int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
•
•
•
sockfd : 주소를 할당하고자 하는 소켓의 파일 디스크립터
myaddr : 할당하고자 하는 주소 정보가 있는 sockaddr_in을
전달해야 하지만 sockaddr 구조체 포인터를 전달한다.
이유는 뒤에 ㅋ
addrlen : 인자로 전달된 주소 정보 구조체의 길이를 전달
왜 sockaddr 인가?
 sockaddr_in 구조체의 포인터도 인자 값으로
받을 수 있어야 하지만 Local UNIX 프로토콜을
위한 sockaddr_un 구조체의 포인터도 받을 수
있어야 했다. 그런데 이 시대에 void 포인터가
아직 없었을 때 이다.
 그래서 sockaddr 구조체에 타입캐스팅으로
넣고 나서 이것을 인자로 하는 것이다.
 무슨말인지 분명 이해가 안될 것이다. 소스를
보면 명확 해 진다 ㅋ
두 구조체의 비교
주소 초기화와 할당(헤더파일 생략)
<- 여기를
잘 보세요