얇지만얇지않은 tcp/ip 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip...

43
목포해양대 해양전자통신공학부 얇지만 얇지 않은 TCP/IP 소켓 프로그래밍 C 2Chap 2. Basic TCP Sockets

Upload: dinhcong

Post on 07-Feb-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부

얇지만 얇지 않은

TCP/IP 소켓 프로그래밍 C 2판

Chap 2. Basic TCP Sockets

Page 2: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

Chap. 2 Basic TCP Sockets

2.1 IPv4 TCP 클라이언트

2.2 IPv4 TCP 서버

2.3 소켓의 생성과 해지

2.4 주소 지정

2.5 소켓에 연결

2.6 소켓을 주소와 바인딩하기

2.7 클라이언트의 연결 요청 처리

2.8 데이터 주고받기

2.9 IPv6의 사용

Page 3: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

소켓(Socket)

소켓이란 무엇인가? 응용 프로그램이 데이터를 주고 받는 추상화 개념(자료 구조)

네트워크 플러그인 인터페이스

TCP/IP를 포함하여 다양한 프로토콜 인터페이스 지원

소켓의 구분 프로토콜(TCP, UDP혹은 기타 프로토콜), 주소, 포트 별로 구분

하나의 응용프로그램이 여러 개의 소켓을 가질 수 있으며 반대로 여러 개의프로그램이 하나의 소켓의 공유가 가능

Page 4: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

소켓 통신 과정

간략화한 소켓 통신 과정

소켓 생성

TCP or UDP

소켓에 주소 정보 할당

IP address, Port number

소켓 연결

클라이언트 소켓과 서버 소켓 연결

bind(), listen(), connect(), accept()

데이터 전송

send(), recv()

Page 5: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP/IP 소켓의 생성

소켓 생성 어떠한 소켓을 생성할 것인가를 명시(프로토콜 종류)

TCP/IP 소켓의 경우

Socket 식별자 UNIX의 파일 식별자와 동일

Windows의 경우, WinSock에서 사용하는 소켓 핸들 Windows의 경우, 파일 핸들과 같지 않음

반환 값: 소켓 식별자인 양의 정수, 에러의 경우 „-1‟

Family Type Protocol

TCPPF_INET

SOCK_STREAM IPPROTO_TCP

UDP SOCK_DGRAM IPPROTO_UDP

int socket(int family,int type,int proto);

Page 6: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP/IP 소켓 식별자

유닉스/리눅스 계열에서 식별자 공간

Descriptor Table

0

1

2

3

4

Data structure for file 0

Data structure for file 1

Family: PF_INETService: SOCK_STREAMLocal IP: 111.22.3.4Remote IP: 123.45.6.78Local Port: 2249Remote Port: 3726

Page 7: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP/IP 소켓의 주소 지정 (1)

struct sockaddr 사용

여러 가지 프로토콜을 사용하기때문에 1)프로토콜 종류,2)주소를 지정해야 함

TCP/IP의 경우는 인터넷 주소임을알리는 AF_INET, IP 주소, Port번호가 필요 IP : IPv4 주소 형식과 IPv6 주소 형식으로 나뉨

Ports : TCP/UDP 관계없이 0~65535 사이의 값사용

well-known (port 0-1023)

dynamic or private (port 1024-65535)

Page 8: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP/IP 소켓의 주소 지정 (2)

범용(Generic) 소켓 주소 구조체struct sockaddr

{

unsigned short sa_family; /* Address family (e.g., AF_INET) */

char sa_data[14]; /* Protocol-specific address information */

};

IPv4에 사용되는 소켓 주소 구조체struct sockaddr_in

{

unsigned short sin_family; /* Internet protocol (AF_INET) */

unsigned short sin_port; /* Port (16-bits) */

struct in_addr sin_addr; /* Internet address (32-bits) */

char sin_zero[8]; /* Not used */

};

struct in_addr

{

unsigned long s_addr; /* Internet address (32-bits) */

};

교재 본문과 비교

sockaddr

sockaddr_in

Family

Family Port

Blob

Internet address Not used

2 bytes 2 bytes 4 bytes 8 bytes

Page 9: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP/IP 소켓의 주소 지정 (3)

IPv6에 사용되는 소켓 주소 구조체struct sockaddr_in6{

sa_family_t sin6_family; // Internet protocol(AF_INET6)

in_port_t sin6_port; // Address port(16bits)

uint32_t sin6_flowinfo; // Flow information

struct in6_addr sin6_addr; // IPv6 address(128bits)

uint32_t sin6_scope_id; // Scope identifier

};

struct in_addr{

uint32_t s_addr[16]; // Internet address(128bits)

};

모든 종류의 sockaddr을 수용하기 위한 구조체struct sockaddr_storage {

sa_family_t

};

Page 10: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

주소 정보를 소켓에 할당

bind()를 사용하여 주소 정보를 생성된소켓에 할당

성공 시 „0‟, 실패 시 „-1‟

int mysock,err;struct sockaddr_in myaddr;char* servIP; /* ex)203.252.164.143 */

mysock = socket(PF_INET,SOCK_STREAM,0);myaddr.sin_family = AF_INET;myaddr.sin_port = htons( portnum );myaddr.sin_addr.s_addr = inet_addr(servIP);

err=bind(mysock, (sockaddr *) &myaddr, sizeof(myaddr));

int bind( int sockfd, struct sockaddr *localaddr, int addrlen);

Page 11: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

클라이언트 – 서버 통신

클라이언트가 먼저 서버에게 연결 요청

서버의 프로세스는 미리 소켓을 열고 대기하고있어야 함

서버는 특정 포트를 열고 대기하여야 하며클라이언트는 이 포트를 알고 있어야 함

클라이언트는 서버에 연결

이때 클라이언트는 서버의 IP, Port 정보를 응용프로그램에게 명시하여 접속 가능

Page 12: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

UDP 연결 흐름도

서버는 이 부분에서멈추고 클라이언트의연결 요청을 기다림

Page 13: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 연결 흐름도

다음 클라이언트로부터 연결 요청을 기다림

연결 요청

Page 14: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

서버의 연결 대기 함수- listen()

TCP와 같은 연결 지향 서버에 사용

소켓의 상태를 대기 상태로 바꿈

socket: 생성된 소켓의 식별자

queuelimit : 연결을 수행중에 다른 연결이들어오면 연결 요청을 queue에 넣고 보류, 이때사용하는 queue의 크기

int listen(int socket, int queuelimit)

Page 15: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

서버의 연결 대기 함수- Accept()

listen()호출 후, accept()를 수행하면클라이언트의 연결 요청(connect())에 대해응답합

passive open

클라이언트와 데이터 송수싞(send/recv)이가능한 새로운 소켓 식별자를 반환

int accept(int socket, struct sockaddr *clientdaddress, int addr_len)

Page 16: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

클라이언트의 연결 함수 -Connect()

클라이언트는 connect()를 호출하여 연결의상태를 „active open‟으로 만듬

foreignAddress는 서버의 IP, port를 담고있는 주소 구조체

int connect(int socket, struct sockaddr *foreignAddress, int addr_len)

Page 17: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

Send(to), Recv(from)

연결이 이루어진 후에는 send/recv를이용하여 데이터의 송수신이 가능

int send(int socket, char *message, int msg_len, int flags)

주어진 소켓을 통하여 messge의 송싞이 가능

int recv(int scoket, char *buffer, int buf_len, int flags)

주어진 소켓을 통해 주어진 버퍼에 데이터를 수싞

Page 18: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

클라이언트와 서버의 통신

클라이언트 : 연결을 초기화 하는 주체

서버 : 수동적으로 연결을 기다림

Client: Bob

“Hi. I‟m Bob.”

Server: Jane

“Hi, Bob. I‟m Jane”

“Nice to meet you, Jane.”

Page 19: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

서버는 클라이언트의 연결을 받아들일 준비를 하고 시작

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

Page 20: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

/* Create socket for incoming connections */

if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

DieWithSystemMessage("socket() failed");

Page 21: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

echoServAddr.sin_family = AF_INET; /* Internet address family */

echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);/* Any incoming interface */

echoServAddr.sin_port = htons(echoServPort); /* Local port */

if (bind(servSock,(struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)

DieWithSystemMessage("bind() failed");

Page 22: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

/* Mark the socket so it will listen for incoming connections */

if (listen(servSock, MAXPENDING) < 0)

DieWithSystemMessage("listen() failed");

Page 23: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

for (;;) /* Run forever */

{

clntLen = sizeof(echoClntAddr);

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0)

DieWithError("accept() failed");

Page 24: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

•서버는 이 시점에서 클라이언트의 연결을 처리하기 위해서 대기

•클라이언트는 서버에 연결 시도

Page 25: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

/* Create a reliable, stream socket using TCP */

if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

DieWithSystemMessage("socket() failed");

Page 26: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

echoServAddr.sin_family = AF_INET; /* Internet address family */

echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */

echoServAddr.sin_port = htons(echoServPort); /* Server port */

if (connect(sock,(struct sockaddr *)&echoServAddr, sizeof(echoServAddr)) < 0)

DieWithSystemMessage ("connect() failed");

Page 27: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0)

DieWithError("accept() failed");

Page 28: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

echoStringLen = strlen(echoString); /* Determine input length */

/* Send the string to the server */

if (send(sock, echoString, echoStringLen, 0) != echoStringLen)

DieWithUserMessage ("send() sent a different number of

bytes than expected");

Page 29: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

/* Receive message from client */

if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)

DieWithSystemMessage("recv() failed");

Page 30: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 상의 서버/클라이언트 통신

클라이언트

1. TCP 소켓 생성

2. 연결 설정

3. 데이터 송수싞

4. 연결 종료

서버

1. TCP 소켓 생성

2. 소켓에 포트 할당

3. 소켓 상태를 대기(listen)로 변경

4. 다음을 반복적으로 수행

a. 새로운 연결을 받아들임

b. 데이터 송수싞

c. 연결을 종료

close(sock); close(clntSocket)

Page 31: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCP 데이터 교환

클라이언트는 사젂에 서버의 주소 정보(IP, port)를 알아야함

서버는 클라이언트가 접속할 포트만 정하고 있음

send()와 recv() 간에는 어떠한 정해진 룰이 없음

Clientsend(“Hello Bob”)

recv() -> “Hi Jane”

Server

recv() -> “Hello ”

recv() -> “Bob”

send(“Hi ”)

send(“Jane”)

Page 32: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

연결 종료

연결을 종료하기 위해서 close()를 사용

파일의 EOF와 유사

Echo Client

send(string)

while (not received entire string)

recv(buffer)

print(buffer)

close(socket)

Echo Server

recv(buffer)while(client has not closed

connection)

send(buffer)recv(buffer)

close(client socket)

Page 33: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

Practical.h

#ifndef PRACTICAL_H_

#define PRACTICAL_H_

#include <stdbool.h>

#include <stdio.h>

#include <sys/socket.h>

// Handle error with user msg

void DieWithUserMessage(const char *msg, const char *detail);

// Handle error with sys msg

void DieWithSystemMessage(const char *msg);

// Print socket address

void PrintSocketAddress(const struct sockaddr *address, FILE *stream);

// Test socket address equality

bool SockAddrsEqual(const struct sockaddr *addr1, const struct sockaddr *addr2);

// Create, bind, and listen a new TCP server socket

int SetupTCPServerSocket(const char *service);

// Accept a new TCP connection on a server socket

int AcceptTCPConnection(int servSock);

// Handle new TCP client

void HandleTCPClient(int clntSocket);

// Create and connect a new TCP client socket

int SetupTCPClientSocket(const char *server, const char *service);

enum sizeConstants {

MAXSTRINGLENGTH = 128,

BUFSIZE = 512,

};

#endif // PRACTICAL_H_

Page 34: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoClient4.c

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <unistd.h>

5 #include <sys/types.h>

6 #include <sys/socket.h>

7 #include <netinet/in.h>

8 #include <arpa/inet.h>

9 #include "Practical.h"

10

11 int main(int argc, char *argv[]) {

12

13 if (argc < 3 || argc > 4) // Test for correct number of arguments

14 DieWithUserMessage("Parameter(s)",

15 "<Server Address> <Echo Word> [<Server Port>]");

16

17 char *servIP = argv[1]; // First arg: server IP address (dotted quad)

18 char *echoString = argv[2]; // Second arg: string to echo

19

20 // Third arg (optional): server port (numeric). 7 is well-known echo port

21 in_port_t servPort = (argc == 4) ? atoi(argv[3]) : 7;

22

23 // Create a reliable, stream socket using TCP

24 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

25 if (sock < 0)

26 DieWithSystemMessage("socket() failed");

Page 35: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoClient4.c

27

28 // Construct the server address structure

29 struct sockaddr_in servAddr; // Server address

30 memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure

31 servAddr.sin_family = AF_INET; // IPv4 address family

32 // Convert address

33 int rtnVal = inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr);

34 if (rtnVal == 0)

35 DieWithUserMessage("inet_pton() failed", "invalid address string");

36 else if (rtnVal < 0)

37 DieWithSystemMessage("inet_pton() failed");

38 servAddr.sin_port = htons(servPort); // Server port

39

40 // Establish the connection to the echo server

41 if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)

42 DieWithSystemMessage("connect() failed");

43

44 size_t echoStringLen = strlen(echoString); // Determine input length

45

46 // Send the string to the server

47 ssize_t numBytes = send(sock, echoString, echoStringLen, 0);

48 if (numBytes < 0)

49 DieWithSystemMessage("send() failed");

50 else if (numBytes != echoStringLen)

51 DieWithUserMessage("send()", "sent unexpected number of bytes");

Page 36: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoClient4.c

52

53 // Receive the same string back from the server

54 unsigned int totalBytesRcvd = 0; // Count of total bytes received

55 fputs("Received: ", stdout); // Setup to print the echoed string

56 while (totalBytesRcvd < echoStringLen) {

57 char buffer[BUFSIZE]; // I/O buffer

58 /* Receive up to the buffer size (minus 1 to leave space for

59 a null terminator) bytes from the sender */

60 numBytes = recv(sock, buffer, BUFSIZE - 1, 0);

61 if (numBytes < 0)

62 DieWithSystemMessage("recv() failed");

63 else if (numBytes == 0)

64 DieWithUserMessage("recv()", "connection closed prematurely");

65 totalBytesRcvd += numBytes; // Keep tally of total bytes

66 buffer[numBytes] = '\0'; // Terminate the string!

67 fputs(buffer, stdout); // Print the echo buffer

68 }

69

70 fputc('\n', stdout); // Print a final linefeed

71

72 close(sock);

73 exit(0);

74 }

Page 37: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoServer4.c

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <sys/types.h>

5 #include <sys/socket.h>

6 #include <netinet/in.h>

7 #include <arpa/inet.h>

8 #include "Practical.h"

9

10 static const int MAXPENDING = 5; // Maximum outstanding connection requests

11

12 int main(int argc, char *argv[]) {

13

14 if (argc != 2) // Test for correct number of arguments

15 DieWithUserMessage("Parameter(s)", "<Server Port>");

16

17 in_port_t servPort = atoi(argv[1]); // First arg: local port

18

19 // Create socket for incoming connections

20 int servSock; // Socket descriptor for server

21 if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

22 DieWithSystemMessage("socket() failed");

23

Page 38: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoServer4.c

24 // Construct local address structure

25 struct sockaddr_in servAddr; // Local address

26 memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure

27 servAddr.sin_family = AF_INET; // IPv4 address family

28 servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface

29 servAddr.sin_port = htons(servPort); // Local port

30

31 // Bind to the local address

32 if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)

33 DieWithSystemMessage("bind() failed");

34

35 // Mark the socket so it will listen for incoming connections

36 if (listen(servSock, MAXPENDING) < 0)

37 DieWithSystemMessage("listen() failed");

38

39 for (;;) { // Run forever

40 struct sockaddr_in clntAddr; // Client address

41 // Set length of client address structure (in-out parameter)

42 socklen_t clntAddrLen = sizeof(clntAddr);

43

44 // Wait for a client to connect

45 int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);

46 if (clntSock < 0)

47 DieWithSystemMessage("accept() failed");

Page 39: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

TCPEchoServer4.c

48

49 // clntSock is connected to a client!

50

51 char clntName[INET_ADDRSTRLEN]; // String to contain client address

52 if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName,

53 sizeof(clntName)) != NULL)

54 printf("Handling client %s/%d\n", clntName, ntohs(clntAddr.sin_port));

55 else

56 puts("Unable to get client address");

57

58 HandleTCPClient(clntSock);

59 }

60 // NOT REACHED

61 }

Page 40: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

HandleTCPClient()

1 void HandleTCPClient(int clntSocket) {

2 char buffer[BUFSIZE]; // Buffer for echo string

3

4 // Receive message from client

5 ssize_t numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);

6 if (numBytesRcvd < 0)

7 DieWithSystemMessage("recv() failed");

8

9 // Send received string and receive again until end of stream

10 while (numBytesRcvd > 0) { // 0 indicates end of stream

11 // Echo message back to client

12 ssize_t numBytesSent = send(clntSocket, buffer, numBytesRcvd, 0);

13 if (numBytesSent < 0)

14 DieWithSystemMessage("send() failed");

15 else if (numBytesSent != numBytesRcvd)

16 DieWithUserMessage("send()", "sent unexpected number of bytes");

17

18 // See if there is more data to receive

19 numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);

20 if (numBytesRcvd < 0)

21 DieWithSystemMessage("recv() failed");

22 }

23

24 close(clntSocket); // Close client socket

25 }

Page 41: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

컴파일 방법 – 리눅스 환경

Native 리눅스/VMware 리눅스/ Cygwin환경

• 유닉스 기반– $ gcc <컴파일 옵션> -o <실행파일> <소스파일들> -lsocket –lnsl

• 리눅스 기반– $ gcc <컴파일 옵션> -o <실행파일> <소스파일들>

Page 42: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

컴파일 방법 – 윈도우 환경

Visual Studio(WinSock) 표준 버클리 소켓과 다르게 WinSock는 아래의 라인을 추가해야한다

기타 시스템 관련 함수들은 버클리 소켓과 완전 동일하지 않다

#include <stdio.h> #include <winsock.h>#include <stdlib.h>

void main() {WSADATA wsaData;

if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {fprintf(stderr, "WSAStartup() failed");

exit(1); }…closesocket(sock);

}

Page 43: 얇지만얇지않은 TCP/IP 소켓프로그래밍 판lily.mmu.ac.kr/lecture/10ic/ch2.pdf · tcp/ip 소켓프로그래밍c 2 ... 4. 연결종료 서버 1. tcp

목포해양대 해양전자통신공학부목포해양대 해양전자통신공학부

컴파일 방법 – 윈도우 환경

윈속 라이브러리 추가(wsock32.lib) menu->project->settings->link->wsock32.lib */