리눅스 소켓 프로그래밍 기초

69
소켓 프로그래밍 기초 2014.11.28 노래방기계 201021448 김광민 201021395 유용우 UNIX PROGRAMMING

Upload: yu-yongwoo

Post on 10-Jan-2017

361 views

Category:

Software


4 download

TRANSCRIPT

소켓프로그래밍기초2014.11.28

노래방기계

201021448 김광민

201021395 유용우

UNIX PROGRAMMING

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주소와호스트명

6 / 69

IP 주소

127.0.0.1

인터넷을 이용할 때 사용하는 주소로 점(.)으로 구분된 32비트 숫자

UNIX PROGRAMMING

소켓프로그래밍기초

IP주소와호스트명

7 / 69

호스트명

www.catholic.ac.kr

호스트명 도메인명

UNIX PROGRAMMING

소켓프로그래밍기초

호스트명과 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

소켓프로그래밍기초

소켓프로그래밍기초

23 / 69

소켓은 응용 계층과 전송 계층을 연결하는 기능을 제공하는

프로그래밍 인터페이스이다.

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

소켓프로그래밍기초

유닉스도메인소켓예제(서버)

48 / 69

클라이언트 접속 수용

클라이언트가 보낸 메시지를 버퍼에 복사함

버퍼를 출력

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

소켓프로그래밍기초

인터넷소켓예제(서버)

52 / 69

클라이언트 연결

클라이언트로 데이터 보내기

소켓 디스크립터 close

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제

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

소켓프로그래밍기초

연습문제 08

• 실행 결과

56 / 69

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.

• 조건2) 서버는 클라이언트의 메시지를 받아 응답을 한다.

• 조건3) 클라이언트가 'q' 를 누를 때 까지 접속이 유지된다.

• 조건4) 서버는 'q' 를 입력 받으면 연결을 종료한다.

=> 클라이언트의 입력을 돌려주는 echo 프로그램 구현

57 / 69

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

58 / 69

Host, Socket 관련 라이브러리 헤더 파일 선언

사용할 포트를 사용자로부터 입력 받아 실행

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

59 / 69

소켓 생성

소켓 기술자와 소켓 구조체 메모리를 매핑

구조체 초기화 및 주소 세팅

클라이언트의 접속을 기다리는 대기 모드로 설정

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

60 / 69

클라이언트와 연결 수립

클라이언트의 메시지를 다시 돌려줌

‘q’를 입력받으면 연결 종료

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

• 실행 결과

61 / 69

Server

Client

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

62 / 69

시 연

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 09

• 조건1) 서버는 클라이언트에서 접속이 가능해야 한다.

• 조건2) 서버는 클라이언트에서 파일명을 입력 받는다.

• 조건3) 서버는 해당 파일명이 존재하는지 확인한다.

• 조건4) 존재한다면 서버는 해당 파일의 내용을 전송한다.

=> 서버의 특정 파일의 내용을 클라이언트로

전송하는 프로그램 작성

63 / 69

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 10

64 / 69

Host, Socket 관련 라이브러리 헤더 파일 선언

사용할 포트를 사용자로부터 입력 받아 실행

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 10

65 / 69

소켓 생성

소켓 기술자와 소켓 구조체 메모리를 매핑

구조체 초기화 및 주소 세팅

클라이언트의 접속을 기다리는 대기 모드로 설정

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 10

66 / 69

파일 기술자 수립

클라이언트로 데이터를 256byte씩 전송

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 10

• 실행 결과

67 / 69

Server

Client

UNIX PROGRAMMING

소켓프로그래밍기초

연습문제 10

68 / 69

시 연

UNIX PROGRAMMING

소켓프로그래밍기초

감사합니다 노래방기계 – 김광민, 유용우

UNIX PROGRAMMING