소켓
- 소켓(socket)은 네트워크를 통한 입/출력을 하기 위해 사용자에게 필요한 수단을 제공하는 응용 프로토콜 인터페이스
- 소켓을 활용한 네트워크 응용 프로그램을 통해 네트워크 상에서 데이터를 송/수신
소켓은 OS 수준 API에서 양방향 네트워크의 종단간 연결과 전송을 할 수 있다.
네트워크 입/출력을 위한 요소
프로토콜(Protocol)
소스 IP 주소(Source IP Address)
소스 포트 번호(Source Port Address)
목적지 IP 주소(Target IP Address)
목적지 포트 번호(Target Port Address)
Socket Interface API
프로그램에서 네트어크 통신 서비스를 받을 때의 Socket API
- <sys/socket.h>
소켓 생성
● socket() 을 사용하여 소켓 생성
- 소켓 프로그래밍에서 통신 창구 역할
- 통신을 위한 end-point 생성
- 소켓 번호 리턴
● 동작
System call: int socket (int domain, int type, int protocol)
- 명시된 domain, type, protocol의 명명되지 않은 소켓을 생성
- 소켓 생성 성공시 : 새로 생성된 소켓에 연관된 파일 기술자 (serverFd)를 반환, 실패시 -1,errno도 설정
serverFd=socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL);
소켓 구조체
● 도메인(domain)
- 서버와 클라이언트 소켓이 존재하는 장소를 지칭
● 유형(type)
- 클라이언트와 서버 사이에 존재할 수 있는 통신 유형 결정
● 프로토콜(protocol)
- 소켓 유형을 구현하는 저급의 수단을 명시
도메인
● 소켓 생성시 인자로 사용
- 주소 바인딩을 하지 않고라도 소켓을 생성할 때 사용 도메인 설정 필요
- BSD 소켓 개발시, TCP/IP 역시 개발 중
●PF(Protocol Family): 프로토콜 군
- PF_INET, PF_LOCAL(PF_UNIX)
●AF(Address Family): 주소 군
- AF_INET, AF_LOCAL(AF_UNIX)
소켓 : 패밀리
●지원하는 프로토콜 그룹 중에서 사용하려는 소켓이 적용될 프로토콜을 선택
Family Protocol |
프로토콜 상수 설명 |
AF_UNIX |
유닉스 기본 파일 체계 소켓 |
AF_INET | IP4의 인터넷 프로토콜 |
AF_INET6 |
IP6의 인터넷 프로토콜 |
AF_NS |
Xerox 네트워크 시스템 프로토콜 |
AF_ISO |
ISO 프로토콜 |
AF_IPX |
Novell IPX 프로토콜 |
AF_APPLETALK |
Appletakl DDS |
● 프로토콜
-여러 소켓 형태를 제공하는 경우 사용, 기본 값은 0
소켓 : 형식 (Type)
● Generic Type과 Protocol-Specific Type으로 구분
- Socket 인터페이스 구현시 C언어에 void 타입이 없었음
- 연결 지향형과 비 인결형, 저수준 소켓 프로토콜 제어형
● 저 수준 프로토콜
- IP 프로토콜과 같은 레벨에 있는 프로토콜을 사용 시 필요
- TCP/UDP 보다 하위 계층으로 사용이 까다로운 반면 직접적인 제어가 가능
Type | 각 Type 상수에 대한 설명 |
SOCK_STREAM | TCP (스트림 소켓) |
SOCK_DGRAM | UDP (데이터그램 소켓) |
SOCK_RAW | Raw 소켓 |
소켓 프로그래밍
주소 지정
● 클라이언트는 일반적으로 주소를 바인딩 하지 않는다.
- 클라이언트가 서버와의 통신을 시도할 때 커널이 자동으로 지정
- 서버와 통신하는 동안만 주소가 유효(임시적 주소)
● 서버는 일반적으로 스스로 주소를 지정 작업 수행 (고정 주소)
IP 주소와 포트번호
● Server에 접속하기 위해 필요한 것
- IP 주소(address), 포트 번호(port number)
● 포트번호
- TCP/IP 프로토콜은 주어진 호스트 컴퓨터 내에서 여러 곳의 목적지로 데이터를 전송하기 위하여 서로 다른 포트를 사용
- 한 클라이언트 컴퓨터가 특정 어플리케이션을 사용하기 위하여 호스트에 연결 할 경우, 그 어플리케이션에 접속할 포트가 사용
포트번호
● 포트 번호를 사용하는 이유
- 동시에 한 개의 IP 주소(Address)로 여러 클라이언트 접속 가능
소켓 네이밍
● 서버가 명명되지 않은 소켓 생성시, bind()를 사용하여 이름 부여, 성공시 0, 실패시 -1
● 동작: System call: int bind(int fd, struct sockadrr* address, int addressLen)
- address에 저장된 소켓 주소를 가지는 파일 기술자 fd를 명명되지 않은 소켓에 연관시킴
- addressLen는 주소 구조체의 길이를 포함
- 입력될 주소의 유형과 값은 소켓 도메인에 의함
기본 자료형
● sockaddr 구조체
- 기본 적인 소켓 주소 구조체, 호환성을 ㅜ이해 존재
- 변수 : 구조체의 크기, Family Type, 소켓의 주소 데이터
● sockaddr_in 구조체
- IPv4 소켓 주소 구조체
- 주소를 담기 위해 in_addr 구조체 사용
- 변수 : 구조체의 크기, Family Type, 소켓의 주소 및 포트 번호
● sockaddr_un 구조체 : 유닉스 호스트 상의 통신
- 유닉스 소켓 주소 ㄱ조체
- 동일 호스트에서의 통신이 일반 TCP 통신보다 두 배 빠름
- 변수 : 소켓 상수, 호스트 경로
도메인에 따른 구조체 항목
● AF_UNIX 도메인
- sockaddr_un 구조체의 항목
항목 | 값부여 |
sun_family | AF_UNIX |
sun_path | 소켓의 완전한 경로 이름으로, 최대 길이는 180문자 |
●AF_INET 도메인
- sockaddr_in 구조체의 항목
항목 | 값부여 |
sin_family | AF_INET |
sin_port | 인터넷트 소켓의 포트 번호 |
sin_addr | in_addr 유형의 구조체 |
sin_zero | Padding Byte(0로 남겨둔다) |
바이트 순서 (Byte Order) 71p lnp_day2
2바이트 이사의 데이터를 메모리에 저장하는 방법, 상위 바이트의 값을 메모리에서 어느쪽으로 두느냐
Big-Endian
상위 바이트 값이 메모리상에 먼저(번지수가 작은 위치) 표시
호스트 바이트 순서(Host Byte Order): Motolora 68000 계열
Little-Endian
하위 바이트 값이 메모리상에서 먼저(번지수가 작은 위치) 표시
호스트 바이트 순서(Host Btye Order): Intel x86 계열
바이트 오더 확인
Linux에서 lscpu 명령으로 확인 가능.
C에서 MBS 값에 따라 확인 가능
endian_conv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
unsigned short host_port=0x1234;
unsigned short net_port;
unsigned long host_addr=0x12345678;
unsigned long net_addr;
net_port=htons(host_port);
net_addr=htonl(host_addr);
printf("Host ordered port: %#x \n",host_port);
printf("Network ordered port: %#x\n",net_port);
printf("Host ordered address: %#lx\n",host_addr);
printf("Network ordered address: %#lx\n",net_addr);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
IP 주소 처리
문자열 <-> 숫자 변환 함수 제공 , 프로그램 작성이 용이
inet_addr() : 문자열 IP 주소를 32비트 IP주소로 변환
inet_aton() : 문자열 IP 주소를 32비트 IP주소로 변환
inet_ntoa() : 32비트 IP주소를 문자열 IP 주소로 변환
inet_network() : IP 주소를 호스트 순서 -> 네트워크 순서로 변환
inet_lnaof() : IP 주소에서 호스트 주소 부분 추출
inet_netof() : IP 주소에서 네트워크 주소 부분 추출
inet_makeaddr() : 분리된 호스트 주소와 네트워크 주소를 결합
주소 변환(1)
● 32비트 이진 바이너리 주소를 'Dotted Decimal' 형식의 문자열로 또는 그 반대로 변환하여 주는 기능
● unsigned long int inet_addr(const char * strptr);
- 'Dotted Decimal' 문자열 형태의 주소를 네트워크 바이트 순서를 갖는 이진 바이너리로 변환
- 입력 값이 적절치 못할 경우 INADDR_NONE('-1')을 반환
- '-1'은 'Dotted Decimal'로 표현시 '255.255.255.255' 이므로 유효성 검사가 반드시 필요
inet_addr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])
{
char *addr1="1.2.3.4";
char *addr2="1.2.3.256";
unsigned long conv_addr=inet_addr(addr1);
if(conv_addr==INADDR_NONE)
printf("Error occured!\n");
else
printf("Network ordered integer addr: %#lx \n",conv_addr);
conv_addr=inet_addr(addr2);
if(conv_addr==INADDR_NONE)
printf("Error occureded\n");
else
printf("Network ordered integer addr: %#lx \n\n",conv_addr);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
int z,sck_inet;
struct sockaddr_in adr_inet;
sck_inet = socket(AF_INET,SOCK_STREAM, 0);
if(sck_inet==-1){
perror("socket()");
return -1;
}
memset(&adr_inet,0,sizeof(adr_inet));
adr_inet.sin_family=AF_INET;
adr_inet.sin_port =htons(8000);
adr_inet.sin_addr.s_addr = inet_addr("127.0.0.1");
if(adr_inet.sin_addr.s_addr == INADDR_NONE) {
perror("bad address.");
return -1;
}
z=bind(sck_inet, (struct sockaddr *)&adr_inet, sizeof(adr_inet));
if(z==-1){
perror("bind()");
return -1;
}
if(listen(sck_inet,5)==-1)
{
printf("listen error");
}
system("netstat -pa --tcp 2>/dev/null | grep inetaddr");
close(sck_inet);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
주소변환(2)
● int inet_aton(const char * strptr, struct int_addr * addrptr);
- 'Dotted Decimal' 형태의 문자열을 바이너리 형태로 변환
- 'strptr'로 들어온 'Dotted Decimal' 형태의 문자열은 변환되어 'in_addr' 타입의 'addrptr'에 저장됨
- 주소가 올바르다면 '0' 이 아닌 값, 그렇지 않다면 '0'을 반환
● char *inet_ntoa(struct inaddr inaddr);
- 'in_addr' 형의 바이너리 주소 'inaddr' 을 'Dotted Decimal' 형태의 문자열로 변경
- 반환 되는 문자열은 정적으로 할당된 버퍼에 저장
- 함수의 연속적인 호출은 버퍼를 중복하여 덮어 쓰므로 주의
inet_ntoa.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include<stdio.h>
#include <string.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])
{
struct sockaddr_in addr1, addr2;
char *str_ptr;
char str_arr[20];
addr1.sin_addr.s_addr=htonl(0x1020304);
addr2.sin_addr.s_addr=htonl(0x1010101);
str_ptr=inet_ntoa(addr1.sin_addr);
strcpy(str_arr,str_ptr);
printf("Dotted-Decimal notation1:%s \n",str_ptr);
inet_ntoa(addr2.sin_addr);
printf("Dotted-Decimal notation2: %s \n",str_ptr);
printf("Dotted-Decimal notation3: %s \n",str_arr);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
주소 변환(3)
● unsigned long inet_network(const char *addr);
- Dotted-quad된 IP 주소를 32비트 호스트 순서 주소로 변환
- 마스크 값을 호스트 비트 혹은 네트워크 비트에 적용 할 때 사용
- 반환 값은 호스트 순서 32비트 IP 주소, 실패시 0xFFFFFFFFF(모두 1)
inet_network()
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
|
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc,char **argv)
{
int x;
const char *addr[] = {
"44.135.86.12",
"127.0.0.1",
"172.16.23.95",
"192.168.9.1"
};
unsigned long net_addr;
for(x=0;x<4;++x){
net_addr = inet_network(addr[x]);
printf("%14s = 0x%08lx net 0x%08lx\n",
addr[x],net_addr,(unsigned long)htonl(net_addr));
};
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
주소변환 (4)
● unsigned long inet_lnaof(struct in_addr addr)
- 32비트 IP 주소(네트워크 바이스 순서) 에서 네트워크 ID 부분을 제외한 호스트 ID 부분만을 변환(호스트 순서)
주소변환 (5)
● unsigned long inet_netof(struct in_addr addr);
- 32비트 IP 주소 (네트워크 바이스 순서) 에서 네트워크 ID 부분을 제외한 네트워크 ID 부분만을 반환(호스트 순서)
● struct in_addr inet_makeaddr (int net, int host);
- 네트워크 ID와 호스트 ID를 결합하여 원래의 IP주소를 생성
inet_makeaddr.c
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
32
33
34
35
36
37
38
39
40
41
42
|
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(int argc, char **argv)
{
int x;
struct sockaddr_in adr_inet;
const char *addr[] = {
"44.135.86.12",
"127.0.0.1",
"172.16.23.95",
"192.168.9.1"
};
unsigned long net, hst;
for(x=0;x<4;++x){
memset(&adr_inet, 0, sizeof(adr_inet));
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
if(!inet_aton(addr[x],&adr_inet.sin_addr)) puts("bad address.");
hst=inet_lnaof(adr_inet.sin_addr);
net = inet_netof(adr_inet.sin_addr);
printf("%14s : net=0x%08lx host=0x%08lx\n",inet_ntoa(adr_inet.sin_addr),net,hst);
memset(&adr_inet, 0, sizeof(adr_inet));
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
adr_inet.sin_addr = inet_makeaddr(net,hst);
printf("inet_makeaddr : %s\n\n",inet_ntoa(adr_inet.sin_addr));
};
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
소켓 주소 획득
● int getsockname(int sockfd, struct sockaddr *name, socklen_t *namelen);
● int geteername(int sockfd, struct sockaddr *name, socklen_t *namelen);
- 지역 소켓과 원격 소켓의 주소를 반환
- 성공시 0, 실패시 -1과 errno 설정
- namelen으로 변수를 지정
getsockname.c
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc,char **argv)
{
int z,sck_inet,len;
struct sockaddr_in adr_inet, inet;
sck_inet = socket(AF_INET,SOCK_STREAM,0);
if(sck_inet == -1){
perror("socket()");
return -1;
}
memset(&adr_inet,0,sizeof adr_inet);
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(8000);
if(!inet_aton("127.0.0.1",&adr_inet.sin_addr)){
perror("bad address");
return -1;
}
z=bind(sck_inet,(struct sockaddr*)&adr_inet, sizeof(adr_inet));
if(z==-1){
perror("bind()");
return -1;
}
len=sizeof(inet);
z=getsockname(sck_inet,(struct sockaddr*)&inet,&len);
if(z==-1){
perror("getsockanme()");
return -1;
}
printf("Address : %s:%u\n",inet_ntoa(inet.sin_addr),
(unsigned)ntohs(inet.sin_port));
close(sck_inet);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
Domain 주소
DNS Server
도메인 이름을 공인IP 주소로 검색해주는 인터넷 서비스
- DNS server는 분산 데이터베이스 시스템
- 로컬 DNS Resolver가 DNS port 53번을 통해 검색
- ROOT -TOP Levle 로 분산된 시스템
DNS (Domain Name System)
영문으로 구성되는 도메인 이름을 IP Address 로 변환하기 위해 필요
도메인 이름과 그에 대응되는 IP Address 가 저장된 테이블을 가지고 있음
IP Address 로의 변환 요청이 발생하면 테이블을 검색하여 변환
원격지 호스트 정보(1)
● struct hostent *gethostbyname(const char * hostname);
- 전달 값으로 호스트의 이름(도메인을)을 받아서 hostent 구조체에 결과 값을 돌려주는 함수
- 도메인 이름을 전달하면 DNS Resolver를 통해서 IP 주소를 검색
● struct hostent *gethostbyaddr(const char * addr, size_t len, int family);
- 호스트의 IP주소 (바이너리 형태의 주소)를 이용하여 해당 호스트에 대한 정보를 저장
- addr은 호스트 IP주소이고 len 은 IP 주소의 크기 (IPv4 = 4, IPv6 = 16)
- IP 주소를 전달하면 DNS Resolver를 통해서 도메인 이름을 검색
● int gethostname(char * name, size_t namelen);
- 현재의 호스트 이름을 반환
- 전달 인자 name은 호스트의 이름을 저장할 곳의 주소
- namelen 은 name의 바이트 길이
-성공한 경우 0, 실패하면 -1
●struct servent *getservbyname(const char * servname, const char * protoname);
- 해당 호스트에서 진행되고 있는 서비스에 대한 각 정보를 서비스에 대한 이름과 해당 프로토콜로 얻을 수 있게 해주는 함수
● struct servent *getservbyport(int port,const char * protoname);
- 해당 호스트에서 진행되고 있는 서비스에 대한 각 정보를 포트 번호로 얻을 수 있게 해주는 함수
- 수행 중 에러 발생 시에는 결과 값으로 반환 NULL 반환
Domain resolving : nslookup
nslookup
- DNS server에 ip, name 을 질의해 얻는다
DNS에 특정 종류(레코드)에 대해서 검색할 때에는 'set type' 명령을 이용
- set types=ns
- set type=all
gethostbyname.c
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
32
33
34
35
|
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])
{
int i;
struct hostent *he;
struct in_addr **addr_list;
if(argc != 2) {
fprintf(stderr,"usage:ghbn hostname\n");
return 1;
}
if((he=gethostbyname(argv[1]))==NULL){
herror("gethostbyname");
return 2;
}
printf("Name : %s\n", he->h_name);
printf("IP addresses: ");
addr_list = (struct in_addr **)he->h_addr_list;
for(i=0;addr_list[i] != NULL; i++)
{
printf("%s ",inet_ntoa(*addr_list[i]));
};
printf("\n");
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
gethostbyaddr.c
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
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
int i;
struct hostent *host;
struct sockaddr_in addr;
if(argc!=2) {
printf("Usage : %s <IP>\n", argv[0]);
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr=inet_addr(argv[1]);
host=gethostbyaddr((char*)&addr.sin_addr, 4, AF_INET);
if(!host)
error_handling("gethost... error");
printf("Official name: %s \n", host->h_name);
for(i=0; host->h_aliases[i]; i++)
printf("Aliases %d: %s \n", i+1, host->h_aliases[i]);
printf("Address type: %s \n",
(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6");
for(i=0; host->h_addr_list[i]; i++)
printf("IP addr %d: %s \n", i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
실습: IP의 Netmask
1. IP Address 준비
2. memcpy로 sockaddr_in에 할당
3. 최상위 바이트 검사
4. 결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
static struct {
unsigned char ip[4];
} addresses[] = {
{{44, 135, 86, 12}}, {{127, 0, 0, 1}}, //샘플 IP
{{172, 16, 23, 95}}, {{192, 168, 9, 1}}
};
for (x = 0; x < 4; ++x) {
memcpy(&adr_inet.sin_addr.s_addr, addresses[x].ip, 4);
msb = *(unsigned char *)&adr_inet.sin_addr.s_addr;
if ((msb & 0x80) == 0x00) { //0x80: 1000
class = 'A';
} else if ((msb & 0xC0) == 0x80) { //0xC0: 1100
class = 'B';
} else if ((msb & 0xE0) == 0xC0) { //0xE0: 1110
class = 'C';
} else if ((msb & 0xF0) == 0xE0) { //0xF0: 1111
class = 'D';
} else {
class = 'E';
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
inet_pton () : 문자 IPv4, IPv6 주소를 바이너리 형으로 전환
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
inet_ntop() : 바이너르 IPv4, IPv6 주소를 문자형으로 전환
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
IPv4, IPv6 네트워크 정보 함수
IPv4 전용 gethostbyaddr, gethostbyname 은 다음 IPv4, IPv6 대응 함수에 통합
getaddrinfo() : 호스트 이름, IP주소 관련 정보를 얻는 함수
getnameinfo() : 주소에서 이름을 변환해 준다
freeaddrinfo() : addrinfo 메모리를 해제
gai_strerror : getaddrinfo, getnameinfo 에러 코드를 문자로 해석
getaddrinfo_a() : 여러 이름을 다룰 수 있다
getaddrinfo()
gethostbyname, gethostbyaddr, inet_addr, inet_aton, inet_pton 통합한 함수
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo (const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
- node : 호스트 이름 혹은 주소 문자열 (주소 문자열은 -> IPv4의 점으로 구분하는 10진 주소 문자열이거나 IPv6의 16진 문자열
- service : 서비스 이름 혹은 10진수로 표현한 포트 번호 문자열
- hints : hint로 줄 addrinfo 구조체에 주소 정보를 채운. 별도의 hint를 제공하지 않을 경우, NULL
- res : 결과 addrinfo
- return : 성공시 0, 그외 값은 에러 코드
addrinfo
네트워크 주소정보(인터넷 주소)와 호스트 이름을 표현
1
2
3
4
5
6
7
8
9
10
11
12
|
struct addrinfo
{
int ai_flags; /* 추가적인 옵션 정. 여러 flag를 bitwise OR-ing */
int ai_family; /* AF_INET, AF_INET6, AF_UNSPEC */
int ai_socktype; /* SOCK_SREAM, SOCK_DGRAM */
int ai_protocol; /* IPv4,IPv6의 IPPROTO_xxx 같은 값. */
socklen_t ai_addrlen; /* socket 주소인 ai_addr의 길이를 나타냄 */
char *ai_canonname; /* 호스트의 canonical name을 나타냄 */
struct sockaddr *ai_addr; /* socket 주소를 나타내는 구조체 포인터 */
struct addrinfo *ai_next; /* 주소정보 구조체 addrinfo는 linked list이다. 다음
데이터의 포인터 */
};
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
getaddrinfo.c
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc,char const *argv[])
{
int status;
struct addrinfo hints;
struct addrinfo *rslt; // result
const char *addr;
if (argc < 2)
{
printf("사용법: %s <domain name>\n", argv[0]);
exit(1);
}
memset(&hints, 0, sizeof hints); //구조체를 0으로 초기화
hints.ai_family = AF_UNSPEC; // IPv4, IPv6 모든 결과
hints.ai_socktype = SOCK_STREAM; // TCP Stream sockets
hints.ai_flags |= AI_CANONNAME;
if((status=getaddrinfo(argv[1],NULL,&hints,&rslt))!=0)
{
fprintf(stderr, "getaddrinfo: %s\n",gai_strerror(status));
exit(EXIT_FAILURE);
}
for(struct addrinfo *aip = rslt; aip!=NULL; aip=aip->ai_next)
{
char addrstr[NI_MAXHOST];
void *ptr; //pointer to binary address
in_port_t port; // port number
switch(aip->ai_family)
{
case AF_INET:
ptr=&((struct sockaddr_in *)aip->ai_addr)->sin_addr;
port = ntohs(((struct sockaddr_in *)aip)->sin_port);
break;
case AF_INET6:
ptr=&((struct sockaddr_in6 *)aip->ai_addr)->sin6_addr;
port=ntohs(((struct sockaddr_in6 *)aip)->sin6_port);
break;
default:
break;
}
// Convert binary to character
inet_ntop(aip->ai_family, ptr, addrstr, sizeof addrstr);
printf("Host name : %s (%s) \n", addrstr, aip->ai_canonname);
}
freeaddrinfo(rslt); // No longer needed
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
'딥러닝 기반 영상인식 개발 전문가 과정 > 리눅스' 카테고리의 다른 글
6월12일 프로세스 기반 다중접속 서버 모델, TCP, 소켓의 다른 옵션 (0) | 2019.06.12 |
---|---|
6월 11일 echo,op server/client 소스, UDP (0) | 2019.06.11 |
6월10일 소켓, 서버/클라이언트 (0) | 2019.06.10 |
6월10일 프로토콜, TCP/IP (0) | 2019.06.10 |
6월 5일 메시지큐, 세마포어, 공유메모리 (0) | 2019.06.05 |