2. 1. TCP/IP 개요
2. IP 주소와 호스트명
3. 포트번호
4. 소켓프로그래밍 기초
5. 소켓 인터페이스 함수
6. 유닉스 도메인 소켓 예제
7. 인터넷 소켓 예제
8. 연습문제
목차
UNIX PROGRAMMING
3. 소켓 프로그래밍 기초
TCP / IP 개요
3 / 69
응용 계층
전송 계층
네트워크 계층
네트워크 접속 계층
하드웨어
SMTP, Telnet,
FTP, HTTP
TCP, UDP
IP, ARP, ICMP
이더넷, FDDI
TCP / IP 계층 UNIX PROGRAMMING
4. 소켓 프로그래밍 기초
TCP / IP 개요
4 / 69
TCP/UDP 프로토콜 비교
UNIX PROGRAMMING
TCP UDP
연결지향형(connection-oriented) 비연결형(connectionless)
신뢰성(reliability) 보장 신뢰성 보장하지 않음
흐름 제어 기능(flow-control) 제공 흐름 제어 기능 없음
순서 보장(sequence) 순서 보장 하지 않음(no sequence)
신뢰성 있는 데이터 전송 스트리밍 서비스에 주로 사용됨
5. 소켓 프로그래밍 기초
TCP / IP 개요
5 / 69
UNIX PROGRAMMING
응용 프로그램
소켓 인터페이스
TCP/UDP
IP
Ethernet
응용 프로그램
소켓 인터페이스
TCP/UDP
IP
EthernetInternet
라우터 라우터
Socket Interface를 이용한
통신 구조
6. IP주소와 호스트명
6 / 69
IP 주소
127.0.0.1
인터넷을 이용할 때 사용하는 주소로 점(.)으로 구분된 32비트 숫자
UNIX PROGRAMMING
소켓 프로그래밍 기초
7. IP주소와 호스트명
7 / 69
호스트명
www.catholic.ac.kr
호스트명 도메인명
UNIX PROGRAMMING
소켓 프로그래밍 기초
8. 호스트명과 IP 주소 변환
8 / 69
file을 먼저 찾아봄 -> /etc/hosts
/etc/nsswitch.conf
파일에서 찾지 못하면? -> DNS 서비스를 이용함
유닉스에서는 호스트명과 IP 주소를 변환하는 함수를 여러가지 형태로 제공한다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
hosts: files dns
9. 호스트명과 IP 주소 읽어오기
9 / 69
#include <netdb.h>
struct hostent* gethostent(void);
int sethostent(int stayopen);
int endhostent(void);
UNIX PROGRAMMING
소켓 프로그래밍 기초
10. 호스트명과 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
소켓 프로그래밍 기초
11. 호스트명과 IP 주소 읽어오기
11 / 69
int sethostent(int stayopen);
stayopen 값이 true면
- 연결된 TCP 소켓이 네임 서버 질의를 위해 사용 되어야 한다는 것을 가리
킨다.
DB의 현재 읽기 위치를 시작 부분으로 재설정하는 함수.
int endhostent(void);
DB를 닫는다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
12. 호스트명과 IP 주소 읽어오기
12 / 69
ex11_1.c
호스트 파일의 처음으로 읽기 위치 설정
호스트 파일에서
차례로 호스트명을 출력
호스트 파일을 닫음
<출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
13. 호스트명으로 정보 검색
13 / 69
#include <netdb.h>
struct hostent* gethostbyname(const char *name);
host명을 인자로 받아 데이터베이스에서 해당 항목을 검색해
hostent 구조체에 저장하고 그 주소를 리턴한다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
14. 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
소켓 프로그래밍 기초
15. IP 주소로 정보 검색
15 / 69
<sys/socket.h>
/usr/src/linux-headers-3.2.0-23/include/linux/socket.h
UNIX PROGRAMMING
소켓 프로그래밍 기초
16. 포트 번호
16 /69
0번 ~ 1023번: 잘 알려진 포트 (well-known port)
1024번 ~ 49151번: 등록된 포트 (registered port)
49152번 ~ 65535번: 동적 포트 (dynamic port)
프로그램 간 상호 정보 교환시 파일이나 임시 저장소를 거치지
않고 직접 연결하기 위한 가상의 논리적 접속
UNIX PROGRAMMING
소켓 프로그래밍 기초
17. 포트 정보 읽어오기
17 / 69
#include <netdb.h>
struct servent* getservent(void);
int setservent(int stayopen);
int endservent(void);
UNIX PROGRAMMING
소켓 프로그래밍 기초
18. 포트 정보 읽어오기
18 / 69
struct servent* getservent(void);
포트 정보를 읽어서 servent 구조체에 저장하고 그 주소를 반환
struct servent {
char* s_name;
char** s_aliases;
int s_port;
char* s_proto;
};
포트명 저장
해당 서비스를 가리키는데 사용하는 다른 이름 저장
포트 번호 저장
서비스에 사용하는 프로토콜의 종류
UNIX PROGRAMMING
소켓 프로그래밍 기초
19. 포트 정보 읽어오기
19 / 69
int setservent(int stayopen);
stayopen 값이 true면
- 포트 정보 데이터베이스를 열어둠.
DB의 현재 읽기 위치를 시작 부분으로 재설정하는 함수.
int endservent(void);
DB를 닫는다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
20. 포트 정보 읽어오기
20 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를
차례로 읽어 출력
DB를 닫음
<출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
21. 서비스명으로 정보 검색
21 / 69
#include <netdb.h>
struct servent* getservbyname(const char *name,
const char* proto);
getservbyname 함수는 포트명을 인자로 받아 DB에서 해당 항목을
검색해서 servent 구조체에 저장하고 그 주소를 리턴한다.
두 번째 인자인 proto에는 “tcp”나 “udp” 또는 NULL을
지정한다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
22. IP 주소로 정보 검색
22 / 69
#include <netdb.h>
struct servent* getservbyport(int port,
const char* proto);
getservbyport 함수는 포트 번호를 인자로 받아 DB에서 해당
항목을 검색해 servent 구조체에 저장하고 그 주소를 리턴한다.
두 번째 인자인 proto에는 “tcp”나 “udp” 또는 NULL을
지정한다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
23. 소켓 프로그래밍 기초
23 / 69
소켓은 응용 계층과 전송 계층을 연결하는 기능을 제공하는
프로그래밍 인터페이스이다.
UNIX PROGRAMMING
소켓 프로그래밍 기초
24. 소켓의 종류
24 / 69
소켓은 같은 호스트에서 프로세스 사이에 통신할 때 사용하는
유닉스 도메인 소켓과 인터넷을 통해 다른 호스트와 통신할 때
사용하는 인터넷 소켓이 있다.
AF_UNIX : 유닉스 도메인 소켓
AF_INET : 인터넷 소켓
UNIX PROGRAMMING
소켓 프로그래밍 기초
25. 포트 정보 읽어오기
25 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를
차례로 읽어 출력
DB를 닫음
<출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
26. 소켓의 통신 방식
26 / 69
TCP/IP 프로토콜에서 전송 계층에서 사용하는 프로토콜로는
TCP와 UDP가 있다. 소켓을 이용할 때도 하부 프로토콜로
TCP/UDP의 사용을 선택해야 한다.
SOCK_STREAM : TCP 프로토콜 사용
SOCK_DGRAM : UDP 프로토콜 사용
UNIX PROGRAMMING
소켓 프로그래밍 기초
27. 소켓 구조체
27 / 69
소켓을 이용한 프로그래밍에서는 소켓의 종류와 IP 주소, 포트
번호 등을 지정하기 위한 구조체를 사용한다.
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[108];
};
AF_UNIX
경로명
<구조체 정의(un.h)>
UNIX PROGRAMMING
소켓 프로그래밍 기초
29. 바이트 순서(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
소켓 프로그래밍 기초
30. 바이트 순서(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. 바이트 순서 함수
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
소켓 프로그래밍 기초
32. NBO를 HBO로 변환하기
32 / 69
ex11_2.c
호스트 파일의 처음으로 읽기 위치 설정
처음 10개의 포트 정보를
차례로 읽어 출력
DB를 닫음
<출력 결과>
ntohs 함수
UNIX PROGRAMMING
소켓 프로그래밍 기초
33. HBO를 NBO로 변환하기
33 / 69
ex11_2.c
telnet이라는 이름으로 검색함
21 포트를 검색함
DB를 닫음
<출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
34. IP 주소의 형태
34 / 69
192.168.0.1
IP 주소는 점 형태로 구분된다.
시스템 내부에 IP가 저장될 때에는 binary 값으로 변환하여 저장됨.
UNIX PROGRAMMING
소켓 프로그래밍 기초
35. 문자열 형태의 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
소켓 프로그래밍 기초
36. 구조체 형태의 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
소켓 프로그래밍 기초
37. IP 주소 변환하기
37 / 69
문자열로 된 IP 주소를 binary 형태로 변환
정수형으로 변환된 IP 주소로 정보를 검색함
호스트명 출력
구조체 형태의 IP 주소를 변환
<출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
38. 소켓 인터페이스 함수
38 / 69
소켓 인터페이스 함수
socket : 소켓 파일기술자 생성
bind : 소켓 파일기술자를 지정된 IP 주소/포트번호와 결합
listen : 클라이언트의 접속 요청 대기
connect : 클라이언트가 서버에 접속 요청
accept : 클라이언트의 접속 허용
recv : 데이터 수신(SOCK_STREAM)
send : 데이터 송신(SOCK_STREAM)
recvfrom : 데이터 수신(SOCK_DGRAM)
sendto : 데이터 송신(SOCK_DGRAM)
close : 소켓 파일기술자 종료
UNIX PROGRAMMING
소켓 프로그래밍 기초
39. 소켓 인터페이스 함수
39 / 69
socket()
bind()
listen()
accept()
recv()
send()
close()
socket()
connect()
send()
recv()
close()
소켓 파일기술자 생성
소켓 파일기술자를 지정된
IP 주소/포트번호와 결합
클라이언트의 접속 요청 대기
클라이언트가 서버에
접속 요청
클라이언트의 접속 허용
데이터 수신
(SOCK_STREAM)
데이터 송신
(SOCK_STREAM)
소켓 파일기술자 종료
UNIX PROGRAMMING
소켓 프로그래밍 기초
40. 소켓 생성하기
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. 소켓에 이름 지정하기
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. 클라이언트 기다리기
42 / 69
#include <sys/types.h>
#include <sys/socket.h>
int listen(int s, int backlog);
s : socket 함수가 생성한 소켓 디스크립터
backlog : 최대 허용 클라이언트 수
UNIX PROGRAMMING
소켓 프로그래밍 기초
43. 연결 요청 수락하기
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. 서버와 연결하기
44 / 69
#include <sys/types.h>
#include <sys/socket.h>
int connect(int s, const struct sockaddr *name, int
namelen);
s : socket 함수가 생성한 소켓 디스크립터
name : 접속을 수락한 클라이언트의 IP 정보
namelen : name의 크기
UNIX PROGRAMMING
소켓 프로그래밍 기초
45. 데이터 보내기
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. 데이터 받기
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. 유닉스 도메인 소켓 예제(서버)
47 / 69
socket 생성
socket 주소 구조체에 값 지정
소켓 디스크립터와 소켓을 합침
클라이언트의 접속을 대기함
UNIX PROGRAMMING
소켓 프로그래밍 기초
48. 유닉스 도메인 소켓 예제(서버)
48 / 69
클라이언트 접속 수용
클라이언트가 보낸 메시지를 버퍼에 복사함
버퍼를 출력
UNIX PROGRAMMING
소켓 프로그래밍 기초
49. 유닉스 도메인 소켓 예제(클라이언트)
49 / 69
socket 생성
socket 주소 구조체에 값 지정
server에 연결 요청
server에 Data send
<서버 출력 결과>
UNIX PROGRAMMING
소켓 프로그래밍 기초
50. 인터넷 소켓 예제(클라이언트)
50 / 69
socket 생성
socket 주소 구조체에 값 지정
server에 연결 요청
server에서 Data를 받음
버퍼에 받은 메시지 출력
UNIX PROGRAMMING
소켓 프로그래밍 기초
51. 인터넷 소켓 예제(서버)
51 / 69
socket 생성
socket 주소 구조체에 값 지정
socket과 주소를 합침
클라이언트 접속 대기
UNIX PROGRAMMING
소켓 프로그래밍 기초
52. 인터넷 소켓 예제(서버)
52 / 69
클라이언트 연결
클라이언트로 데이터 보내기
소켓 디스크립터 close
UNIX PROGRAMMING
소켓 프로그래밍 기초
54. 연습문제 08
• 조건1) /etc/hosts에 특정 호스트가 있는지 확인
• 조건2) 해당 호스트가 없으면 DNS 조회하여 결과 출력
=> 특정 호스트의 IP주소를 출력하는 프로그램 작성
54 / 69
UNIX PROGRAMMING
소켓 프로그래밍 기초
55. 연습문제 08
• 조건1) 서버는 클라이언트 메시지를 받아 응답을 한다.
• 조건2) 클라이언트 'q' 를 누를 때 까지 반복한다.
55 / 69
호스트 관련 라이브러리 헤더 파일 선언
host를 받아 IP를 조회 (hosts->DNS)
IP정보를 in_addr 구조체로 복사
UNIX PROGRAMMING
소켓 프로그래밍 기초
56. 연습문제 08
• 실행 결과
56 / 69
UNIX PROGRAMMING
소켓 프로그래밍 기초
57. 연습문제 09
• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.
• 조건2) 서버는 클라이언트의 메시지를 받아 응답을 한다.
• 조건3) 클라이언트가 'q' 를 누를 때 까지 접속이 유지된다.
• 조건4) 서버는 'q' 를 입력 받으면 연결을 종료한다.
=> 클라이언트의 입력을 돌려주는 echo 프로그램 구현
57 / 69
UNIX PROGRAMMING
소켓 프로그래밍 기초
58. 연습문제 09
58 / 69
Host, Socket 관련 라이브러리 헤더 파일 선언
사용할 포트를 사용자로부터 입력 받아 실행
UNIX PROGRAMMING
소켓 프로그래밍 기초
59. 연습문제 09
59 / 69
소켓 생성
소켓 기술자와 소켓 구조체 메모리를 매핑
구조체 초기화 및 주소 세팅
클라이언트의 접속을 기다리는 대기 모드로 설정
UNIX PROGRAMMING
소켓 프로그래밍 기초
60. 연습문제 09
60 / 69
클라이언트와 연결 수립
클라이언트의 메시지를 다시 돌려줌
‘q’를 입력받으면 연결 종료
UNIX PROGRAMMING
소켓 프로그래밍 기초
61. 연습문제 09
• 실행 결과
61 / 69
Server
Client
UNIX PROGRAMMING
소켓 프로그래밍 기초
62. 연습문제 09
62 / 69
시 연
UNIX PROGRAMMING
소켓 프로그래밍 기초
63. 연습문제 09
• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.
• 조건2) 서버는 클라이언트에서 파일명을 입력 받는다.
• 조건3) 서버는 해당 파일명이 존재하는지 확인한다.
• 조건4) 존재한다면 서버는 해당 파일의 내용을 전송한다.
=> 서버의 특정 파일의 내용을 클라이언트로
전송하는 프로그램 작성
63 / 69
UNIX PROGRAMMING
소켓 프로그래밍 기초
64. 연습문제 10
64 / 69
Host, Socket 관련 라이브러리 헤더 파일 선언
사용할 포트를 사용자로부터 입력 받아 실행
UNIX PROGRAMMING
소켓 프로그래밍 기초
65. 연습문제 10
65 / 69
소켓 생성
소켓 기술자와 소켓 구조체 메모리를 매핑
구조체 초기화 및 주소 세팅
클라이언트의 접속을 기다리는 대기 모드로 설정
UNIX PROGRAMMING
소켓 프로그래밍 기초
66. 연습문제 10
66 / 69
파일 기술자 수립
클라이언트로 데이터를 256byte씩 전송
UNIX PROGRAMMING
소켓 프로그래밍 기초
67. 연습문제 10
• 실행 결과
67 / 69
Server
Client
UNIX PROGRAMMING
소켓 프로그래밍 기초
68. 연습문제 10
68 / 69
시 연
UNIX PROGRAMMING
소켓 프로그래밍 기초