리눅스 소켓 프로그래밍 기초
TRANSCRIPT
1. TCP/IP 개요
2. IP 주소와호스트명
3. 포트번호
4. 소켓프로그래밍기초
5. 소켓인터페이스함수
6. 유닉스도메인소켓예제
7. 인터넷소켓예제
8. 연습문제
목차
UNIX PROGRAMMING
소켓프로그래밍기초
TCP / IP 개요
3 / 69
응용 계층
전송 계층
네트워크 계층
네트워크 접속 계층
하드웨어
SMTP, Telnet,FTP, HTTP
TCP, UDP
IP, ARP, ICMP
이더넷, FDDI
TCP / IP 계층 UNIX PROGRAMMING
소켓프로그래밍기초
TCP / IP 개요
4 / 69
TCP/UDP 프로토콜 비교
UNIX PROGRAMMING
TCP UDP
연결지향형(connection-oriented) 비연결형(connectionless)
신뢰성(reliability) 보장 신뢰성 보장하지 않음
흐름 제어 기능(flow-control) 제공 흐름 제어 기능 없음
순서 보장(sequence) 순서 보장 하지 않음(no sequence)
신뢰성 있는 데이터 전송 스트리밍 서비스에 주로 사용됨
소켓프로그래밍기초
TCP / IP 개요
5 / 69
UNIX PROGRAMMING
응용 프로그램
소켓 인터페이스
TCP/UDP
IP
Ethernet
응용 프로그램
소켓 인터페이스
TCP/UDP
IP
EthernetInternet라우터 라우터
Socket Interface를 이용한통신 구조
호스트명과 IP주소변환
8 / 69
file을 먼저 찾아봄 -> /etc/hosts
/etc/nsswitch.conf
파일에서 찾지 못하면? -> DNS 서비스를 이용함
유닉스에서는 호스트명과 IP 주소를 변환하는 함수를 여러가지 형태로 제공한다.
UNIX PROGRAMMING
소켓프로그래밍기초
hosts: files dns
호스트명과 IP주소읽어오기
9 / 69
#include <netdb.h>
struct hostent* gethostent(void);
int sethostent(int stayopen);
int endhostent(void);
UNIX PROGRAMMING
소켓프로그래밍기초
호스트명과 IP주소읽어오기
10 / 69
struct hostent* gethostent(void);
host명과 IP 주소를 읽어서 hostent 구조체에 저장하고
그 주소를 리턴한다.
struct hostent {char* h_name;char** h_aliases;int h_addrtype;int h_length;char** h_addr_list;
};
호스트명 저장
호스트를 가리키는데 사용하는 다른 이름 저장
호스트 주소 형식 지정
주소의 길이
해당 호스트의 주소 목록 저장
UNIX PROGRAMMING
소켓프로그래밍기초
호스트명과 IP주소읽어오기
11 / 69
int sethostent(int stayopen);
stayopen 값이 true면- 연결된 TCP 소켓이 네임 서버 질의를 위해 사용 되어야 한다는 것을 가리킨다.
DB의 현재 읽기 위치를 시작 부분으로 재설정하는 함수.
int endhostent(void);
DB를 닫는다.
UNIX PROGRAMMING
소켓프로그래밍기초
호스트명과 IP주소읽어오기
12 / 69
ex11_1.c
호스트 파일의 처음으로 읽기 위치 설정
호스트 파일에서차례로 호스트명을 출력
호스트 파일을 닫음
<출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
호스트명으로정보검색
13 / 69
#include <netdb.h>
struct hostent* gethostbyname(const char *name);
host명을 인자로 받아 데이터베이스에서 해당 항목을 검색해
hostent 구조체에 저장하고 그 주소를 리턴한다.
UNIX PROGRAMMING
소켓프로그래밍기초
IP 주소로정보검색
14 / 69
#include <netdb.h>
struct hostent* gethostbyaddr(const char* addr, int len, int type);
IP 주소를 인자로 받아 DB에서 해당 항목을 검색해 hostent
구조체에 저장하고 그 주소를 리턴한다.
type은 주소의 형식으로 <sys/socket.h> 파일에 정의된 주소
형식중 하나를 지정해야 한다.
UNIX PROGRAMMING
소켓프로그래밍기초
IP 주소로정보검색
15 / 69
<sys/socket.h>
/usr/src/linux-headers-3.2.0-23/include/linux/socket.h
UNIX PROGRAMMING
소켓프로그래밍기초
포트번호
16 /69
0번 ~ 1023번: 잘 알려진 포트 (well-known port)
1024번 ~ 49151번: 등록된 포트 (registered port)
49152번 ~ 65535번: 동적 포트 (dynamic port)
프로그램 간 상호 정보 교환시 파일이나 임시 저장소를 거치지
않고 직접 연결하기 위한 가상의 논리적 접속
UNIX PROGRAMMING
소켓프로그래밍기초
포트정보읽어오기
17 / 69
#include <netdb.h>
struct servent* getservent(void);
int setservent(int stayopen);
int endservent(void);
UNIX PROGRAMMING
소켓프로그래밍기초
포트정보읽어오기
18 / 69
struct servent* getservent(void);
포트 정보를 읽어서 servent 구조체에 저장하고 그 주소를 반환
struct servent {char* s_name;char** s_aliases;int s_port;char* s_proto;
};
포트명 저장
해당 서비스를 가리키는데 사용하는 다른 이름 저장
포트 번호 저장
서비스에 사용하는 프로토콜의 종류
UNIX PROGRAMMING
소켓프로그래밍기초
포트정보읽어오기
19 / 69
int setservent(int stayopen);
stayopen 값이 true면- 포트 정보 데이터베이스를 열어둠.
DB의 현재 읽기 위치를 시작 부분으로 재설정하는 함수.
int endservent(void);
DB를 닫는다.
UNIX PROGRAMMING
소켓프로그래밍기초
포트정보읽어오기
20 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를차례로 읽어 출력
DB를 닫음<출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
서비스명으로정보검색
21 / 69
#include <netdb.h>
struct servent* getservbyname(const char *name, const char* proto);
getservbyname 함수는 포트명을 인자로 받아 DB에서 해당 항목을
검색해서 servent 구조체에 저장하고 그 주소를 리턴한다.
두 번째 인자인 proto에는 “tcp”나 “udp” 또는 NULL을
지정한다.
UNIX PROGRAMMING
소켓프로그래밍기초
IP 주소로정보검색
22 / 69
#include <netdb.h>
struct servent* getservbyport(int port,const char* proto);
getservbyport 함수는 포트 번호를 인자로 받아 DB에서 해당
항목을 검색해 servent 구조체에 저장하고 그 주소를 리턴한다.
두 번째 인자인 proto에는 “tcp”나 “udp” 또는 NULL을
지정한다.
UNIX PROGRAMMING
소켓프로그래밍기초
소켓의종류
24 / 69
소켓은 같은 호스트에서 프로세스 사이에 통신할 때 사용하는
유닉스 도메인 소켓과 인터넷을 통해 다른 호스트와 통신할 때
사용하는 인터넷 소켓이 있다.
AF_UNIX : 유닉스 도메인 소켓
AF_INET : 인터넷 소켓
UNIX PROGRAMMING
소켓프로그래밍기초
포트정보읽어오기
25 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를차례로 읽어 출력
DB를 닫음<출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
소켓의통신방식
26 / 69
TCP/IP 프로토콜에서 전송 계층에서 사용하는 프로토콜로는
TCP와 UDP가 있다. 소켓을 이용할 때도 하부 프로토콜로
TCP/UDP의 사용을 선택해야 한다.
SOCK_STREAM : TCP 프로토콜 사용
SOCK_DGRAM : UDP 프로토콜 사용
UNIX PROGRAMMING
소켓프로그래밍기초
소켓구조체
27 / 69
소켓을 이용한 프로그래밍에서는 소켓의 종류와 IP 주소, 포트
번호 등을 지정하기 위한 구조체를 사용한다.
struct sockaddr_un {sa_family_t sun_family;char sun_path[108];
};
AF_UNIX
경로명
<구조체 정의(un.h)>
UNIX PROGRAMMING
소켓프로그래밍기초
소켓구조체
28 / 69
struct sockaddr_in {sa_family_t sin_family;in_port_t sin_port;struct in_addr sin_addr;
};
AF_INET
포트명
struct in_addr {in_addr_t s_addr;
};
32bit IP Address
in_addr 구조체
UNIX PROGRAMMING
소켓프로그래밍기초
바이트순서(Byte ordering)
29 / 69
빅 엔디언 방식 리틀 엔디언 방식
메모리의 낮은 주소에 정수의첫 바이트를 저장TCP/IP의 바이트 순서
메모리의 높은 주소에 정수의첫 바이트를 저장Intel의 바이트 순서
0x12345678 저장?[0] [1] [2] [3]
0x12 0x34 0x56 0x78
[0] [1] [2] [3]
0x78 0x56 0x34 0x12
UNIX PROGRAMMING
소켓프로그래밍기초
바이트순서(Byte ordering)
30 / 69
데이터 전이도
클라이언트 서버
0x78 0x56 0x34 0x12
0x12 0x34 0x56 0x78 0x12 0x34 0x56 0x78
0x78 0x56 0x34 0x12
BYTE ORDER 변경 BYTE ORDER 변경
TCP/IP에서데이터 전송
HBO(Host Byte Order)
NBO(Network Byte Order) NBO(Network Byte Order)
UNIX PROGRAMMING
소켓프로그래밍기초
바이트순서함수
31 / 69
#include <sys/types.h>#include <netinet/in.h>#include <inttypes.h>
uint32_t htonl(unit32_t hostlong);uint16_t htons(unit16_t hostshort);uint32_t ntohl(unit32_t netlong);uint16_t ntohs(unit16_t netshort);
htonl 함수는 32비트 HBO를 32비트 NBO로 변환한다.htons 함수는 16비트 HBO를 16비트 NBO로 변환한다.ntohl 함수는 32비트 NBO를 32비트 HBO로 변환한다.ntohs 함수는 16비트 HBO를 16비트 NBO로 변환한다.
UNIX PROGRAMMING
소켓프로그래밍기초
NBO를HBO로변환하기
32 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를차례로 읽어 출력
DB를 닫음<출력 결과>
ntohs 함수
UNIX PROGRAMMING
소켓프로그래밍기초
HBO를NBO로변환하기
33 / 69
ex11_2.c
telnet이라는 이름으로 검색함
21 포트를 검색함
DB를 닫음<출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
IP 주소의형태
34 / 69
192.168.0.1IP 주소는 점 형태로 구분된다.
시스템 내부에 IP가 저장될 때에는 binary 값으로 변환하여 저장됨.
UNIX PROGRAMMING
소켓프로그래밍기초
문자열형태의 IP를숫자형태로변환
35 / 69
inet_addr 함수는 IP 주소를 문자열로 받아 이를 binary 값으로
변환하여 리턴한다.
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp);
UNIX PROGRAMMING
소켓프로그래밍기초
구조체형태의 IP를숫자형태로변환
36 / 69
inet_addr 함수는 IP 주소를 구조체로 받아 이를 binary 값으로
변환하여 리턴한다.
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>
char* inet_ntoa(const struct in_addr in);
UNIX PROGRAMMING
소켓프로그래밍기초
IP 주소변환하기
37 / 69
문자열로 된 IP 주소를 binary 형태로 변환
정수형으로 변환된 IP 주소로 정보를 검색함
호스트명 출력
구조체 형태의 IP 주소를 변환
<출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
소켓인터페이스함수
38 / 69
소켓 인터페이스 함수
socket : 소켓 파일기술자 생성
bind : 소켓 파일기술자를 지정된 IP 주소/포트번호와 결합
listen : 클라이언트의 접속 요청 대기
connect : 클라이언트가 서버에 접속 요청
accept : 클라이언트의 접속 허용
recv : 데이터 수신(SOCK_STREAM)
send : 데이터 송신(SOCK_STREAM)
recvfrom : 데이터 수신(SOCK_DGRAM)
sendto : 데이터 송신(SOCK_DGRAM)
close : 소켓 파일기술자 종료UNIX PROGRAMMING
소켓프로그래밍기초
소켓인터페이스함수
39 / 69
socket()
bind()
listen()
accept()
recv()
send()
close()
socket()
connect()
send()
recv()
close()
소켓 파일기술자 생성
소켓 파일기술자를 지정된
IP 주소/포트번호와 결합
클라이언트의 접속 요청 대기
클라이언트가 서버에
접속 요청클라이언트의 접속 허용
데이터 수신(SOCK_STREAM)
데이터 송신
(SOCK_STREAM)
소켓 파일기술자 종료
UNIX PROGRAMMING
소켓프로그래밍기초
소켓생성하기
40 / 69
#include <sys/types.h>#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain : 소켓 종류(AF_UNIX, AF_INET)type : 통신방식(TCP, UDP)protocol : 소켓에 이용할 프로토콜
UNIX PROGRAMMING
소켓프로그래밍기초
소켓에이름지정하기
41 / 69
#include <sys/types.h>#include <sys/socket.h>
int bind(int s, const struct sockaddr* name, int namelen);
s : socket 함수가 생성한 소켓 디스크립터name : 소켓의 이름을 표현하는 구조체namelen : name의 크기
UNIX PROGRAMMING
소켓프로그래밍기초
클라이언트기다리기
42 / 69
#include <sys/types.h>#include <sys/socket.h>
int listen(int s, int backlog);
s : socket 함수가 생성한 소켓 디스크립터backlog : 최대 허용 클라이언트 수
UNIX PROGRAMMING
소켓프로그래밍기초
연결요청수락하기
43 / 69
#include <sys/types.h>#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t*addrlen);
s : socket 함수가 생성한 소켓 디스크립터addr : 접속을 수락한 클라이언트의 IP 정보addrlen : addr의 크기
UNIX PROGRAMMING
소켓프로그래밍기초
서버와연결하기
44 / 69
#include <sys/types.h>#include <sys/socket.h>
int connect(int s, const struct sockaddr *name, intnamelen);
s : socket 함수가 생성한 소켓 디스크립터name : 접속을 수락한 클라이언트의 IP 정보namelen : name의 크기
UNIX PROGRAMMING
소켓프로그래밍기초
데이터보내기
45 / 69
#include <sys/types.h>#include <sys/socket.h>
ssize_t send(int s, const void *msg, size_t len, int flags);
s : socket 함수가 생성한 소켓 디스크립터msg : 전송할 메시지를 저장한 메모리 주소len : 메시지의 크기flags : 데이터를 주고받는 방법을 지정한 플래그
UNIX PROGRAMMING
소켓프로그래밍기초
데이터받기
46 / 69
#include <sys/types.h>#include <sys/socket.h>
ssize_t recv(int s, void *buf, size_t len, int flags);
s : socket 함수가 생성한 소켓 디스크립터buf : 전송받은 메시지를 저장한 메모리 주소len : 버퍼의 크기flags : 데이터를 주고받는 방법을 지정한 플래그
UNIX PROGRAMMING
소켓프로그래밍기초
유닉스도메인소켓예제(서버)
47 / 69
socket 생성
socket 주소 구조체에 값 지정
소켓 디스크립터와 소켓을 합침
클라이언트의 접속을 대기함
UNIX PROGRAMMING
소켓프로그래밍기초
유닉스도메인소켓예제(클라이언트)
49 / 69
socket 생성
socket 주소 구조체에 값 지정
server에 연결 요청
server에 Data send
<서버 출력 결과>
UNIX PROGRAMMING
소켓프로그래밍기초
인터넷소켓예제(클라이언트)
50 / 69
socket 생성
socket 주소 구조체에 값 지정
server에 연결 요청
server에서 Data를 받음
버퍼에 받은 메시지 출력
UNIX PROGRAMMING
소켓프로그래밍기초
인터넷소켓예제(서버)
51 / 69
socket 생성
socket 주소 구조체에 값 지정
socket과 주소를 합침
클라이언트 접속 대기
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 08
• 조건1) /etc/hosts에 특정 호스트가 있는지 확인
• 조건2) 해당 호스트가 없으면 DNS 조회하여 결과 출력
=> 특정 호스트의 IP주소를 출력하는 프로그램 작성
54 / 69
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 08
• 조건1) 서버는 클라이언트 메시지를 받아 응답을 한다.
• 조건2) 클라이언트 'q' 를 누를 때 까지 반복한다.
55 / 69
호스트 관련 라이브러리 헤더 파일 선언
host를 받아 IP를 조회 (hosts->DNS)
IP정보를 in_addr 구조체로 복사
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 09
• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.
• 조건2) 서버는 클라이언트의 메시지를 받아 응답을 한다.
• 조건3) 클라이언트가 'q' 를 누를 때 까지 접속이 유지된다.
• 조건4) 서버는 'q' 를 입력 받으면 연결을 종료한다.
=> 클라이언트의 입력을 돌려주는 echo 프로그램 구현
57 / 69
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 09
59 / 69
소켓 생성
소켓 기술자와 소켓 구조체 메모리를 매핑
구조체 초기화 및 주소 세팅
클라이언트의 접속을 기다리는 대기 모드로 설정
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 09
• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.
• 조건2) 서버는 클라이언트에서 파일명을 입력 받는다.
• 조건3) 서버는 해당 파일명이 존재하는지 확인한다.
• 조건4) 존재한다면 서버는 해당 파일의 내용을 전송한다.
=> 서버의 특정 파일의 내용을 클라이언트로
전송하는 프로그램 작성
63 / 69
UNIX PROGRAMMING
소켓프로그래밍기초
연습문제 10
65 / 69
소켓 생성
소켓 기술자와 소켓 구조체 메모리를 매핑
구조체 초기화 및 주소 세팅
클라이언트의 접속을 기다리는 대기 모드로 설정
UNIX PROGRAMMING
소켓프로그래밍기초