Lecture note5

Download Report

Transcript Lecture note5

TCP Client/Server Program
School of Electronics and Information.
Kyung Hee University.
Dae Sun Kim
<[email protected]>
1
TCP Client Program
 작성절차
TCP Client
socket()
소켓 개설
sockaddr_in 구성
서버의 IP 주소와
포트번호 지정
connect()
서버로 연결 요구
send(), recv()
데이터 송수신
close()
2
TCP Client Program (Cont’d)
 socket() 호출시 소켓번호와 소켓 인터페이스의 관계
socket()
리턴
호출
소켓번호
1. 프로토콜
2. 자신의 IP 주소
3. 자신의 포트번호
4. 상대방 IP 주소
5. 상대방 포트번호
소켓 인터페이스
TCP/IP
네트워크
3
TCP Client Program (Cont’d)
 connect()
int connect( int s, const struct sockaddr *addr, int addrlen);
s : 서버와 연결시킬 소켓번호

소켓번호이며 연결이 이루어지고 나면 앞으로 이 소켓번호를 사용해서 서버와
통신을 하게 된다
addr : 상대방 서버의 소켓주소 구조체

연결할 상대방 서버의 IP 주소와 2byte의 포트번호를 포함하고 있는 소켓주소
구조체 sockaddr_in을 지정
addrlen : 구조체 *addr의 크기
4
TCP Client Program (Cont’d)
 connect() 호출시 소켓번호와 소켓주소의 관계
응용 프로그램(Client)
socket()
connect()
소켓번호
1. 프로토콜
소켓 인터페이스
2. 자신의 IP 주소
3. 자신의 포트번호
4. 상대방 IP 주소
5. 상대방 포트번호
TCP/IP
네트워크
5
TCP Client Program (Cont’d)
 TCP 소켓의 데이터 송수신 함수
6
TCP Client Program (Cont’d)
 send(), write() 함수
스트림형(TCP) 소켓을 통하여 데이터를 송신하는 함수
데이터를 전송할 소켓번호(s), 송신할 데이터 버퍼(buf), 전송할 데이터
크기(length)를 지정
send() 와 write() 두 함수의 동작은 동일
차이점

send()는 flag 인자를 추가로 사용
한 IP 데이터그램에 실어서 전송할 수 있는 최대 데이터 크기인 최대
세그먼트 크기(MSS: Maximum Segment Size)보다 큰 데이터를 write() 나
send()로 보내면 전체 데이터가 MSS 크기로 분할되어 여러번에 나누어
전송된다.
7
TCP Client Program (Cont’d)
 recv(), read() 함수
스트림형 소켓을 통하여 데이터를 수신하는 함수이며 데이터를 수신할
소켓번호(s), 수신버퍼(buf), 읽을 데이터 크기(length)를 지정
두 함수 모두 실제로 읽은 데이터 크기를 바이트 단위로 리턴
recv(), read() 두 함수의 동작은 동일
차이점

recv()는 flag 인자를 추가로 사용
8
프로그램 예제 확인 #1
 daytime Client
유닉스 서버가 제공하는 daytime 서비스를 이용하는 클라이언트 프로그램
실행결과
[root]# tcp_daytimecli 163.180.116.233
Wed Jan 1 09:00:21 2003
주요 코드
s = socket(PF_INET, SOCK_STREAM,0);

프로토콜 체계로는 인터넷을(IPv4 기반), 서비스는 연결지향형(TCP)을 지정
9
프로그램 예제 확인 #1
struct sockaddr_in servaddr; // 서버의 소켓주소 구조체
servaddr.sin_familly = AF_INET;
// 주소 체계 선택
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
// 32비트 IP 주소로 변환
servaddr.sin_port = htons(13);// daytime 서비스 포트번호
주소 체계를 인터넷(IPv4)으로 지정하고 서버의 IP 주소와 포트번호를
소켓주소 구조체 sever_addr에 기록
Inet_pton() 함수는 사용자가 명령 인자로 입력한 10진 형태의 IP 주소 문자열
argv[1]을 32비트 IP 주소로 변환하는 함수
daytime 서비스를 받기 위하여 well-known 포트번호 13번 지정
10
프로그램 예제 확인 #1
connect(s, (struct sockaddr *) &servaddr, sizeof(servaddr));
서버에 연결을 효청하기 위해 connect() 함수 호출
N = read(s, buf, sizeof(buf)); // recv(s, buf, sizeof(buf), 0)
도 같은 동작을 한다.
서버와 연결된 후, 서버가 보내오는 문자열(날짜와 시간)을 수신하기 위해
클라이언트는 read()를 호출(파일 입출력과 유사)
 프로그램명: tcp_daytimecli.c
11
프로그램 예제 확인 #2
 TCP Echo Client
Echo service를 이용하는 client 프로그램
실행결과
[root]# tcp_echo 163.180.116.233
입력: abcdefg
수신메시지: abcdefg
주요 코드
servaddr.sin_port = htons(7);

Echo 는 포트번호 7을 사용
12
프로그램 예제 확인 #2
fgets(buf, sizeof(buf), stdin);
connect()를 호출한 후 서버와 연결이 완료되면 서버로 전송할 문자열을
키보드를 통해 입력 받음
fgets() 함수는 스트링 문자열을 입력받는 함수로 첫번째 인자(buf)는
문자열을 저장할 버퍼, 두 번째 인자는 버퍼의 크기, 세번째 인자는 입력
스트림 포인터
입력 스트림 포인터로 stdin을 지정(stdin은 FILE 포인터 타입의 전역변수로
표준 입력 파일인 키보드를 가리킴)
fgets()로 키보드에서 입력받은 문자열을 write()를 이용해 서버로 전송하고
서버가 echo 시켜준 문자열을 read()로 수신하여 화면에 출력
 프로그램명: tcp_echocli.c
13
프로그램 예제 확인 #3
 포트번호 배정
Client에서는 소켓에 특정 포트번호를 배정(bind) 하지 않고 시스템이 임의로
배정
TCP 소켓인 경우는 connect() 호출이 성공한 후에 포트번호 배정
UDP 소켓인 경우는 첫 번째 메시지를 보내는 sendto() 함수가 성공한 후에
배정
getsockname() : 자신의 호스트에 있는 소켓 정보를 알아내는 함수
getpeername() : TCP로 연결된 상대방의 소켓 정보를 얻는 함수
 프로그램명 : port_number.c
14
TCP Server Program
 작성절차
Iterative TCP Server
socket()
bind()
소켓번호와
소켓주소의 결합
listen()
연결을 기다림
accept()
read() 서비스 처리, write()
N
소켓 개설
연결수락
클라이언트의 요구를
처리한 후 결과
Finished ?
Y
closed()
15
TCP Server Program (Cont’d)
 socket()
소켓의 생성
socket(PF_INET, SOCK_STREAM,0)
 bind()
int bind(int sockfd, struct sockaddr * myaddr, int addrlen);
socket()으로 생성된 소켓은 그 응용 프로그램 내에서 유일한 번호인
소켓번호를 배정받는다. 그러나 이번호는 응용 프로그램만 알고 있는
번호이므로 이 프로그램이 컴퓨터 외부와 통신하려면 이 소켓번호와
소켓주소(IP 주소 + 포트번호)를 연결해 두어야 하며 이를 위해 bind()가
사용된다.
16
TCP Server Program (Cont’d)
 bind() 호출시 소켓번호와 소켓주소의 관계
응용프로그램(서버)
socket()
bind()
연결
소켓번호
1. 프로토콜
2. 자신의 IP 주소
3. 자신의 포트번호
4. 상대방 IP 주소
5. 상대방 포트번호
소켓 인터페이스
TCP/IP
네트워크
17
TCP Server Program (Cont’d)
 listen()
int listen(int s, int backlog);
int s : 소켓번호
int backlog : 연결을 기다리는 클라이언트의 최대 수
능동적 소켓 : 요청을 보내는 클라이언트 소켓
수동적 소켓 : 연결요청을 받아들이는 서버의 소켓
socket() 함수에 의해 성성되는 소켓은 기본으로 능동적 소켓이므로 이를
수동적 소켓으로 변경하려면 listen() 함수를 호출해야 함.
함수호출 성공시에는 0, 실패 시에는 -1이 리턴
18
TCP Server Program (Cont’d)
19
TCP Server Program (Cont’d)
 accept()
int accept(int s, struct sockaddr *addr, int addrlen);
int s : 소켓번호
struct sockaddr *addr : 연결요청을 한 클라이언트의 소켓주소 구조체
int addrlen : *addr 구조체 크기의 포인터
accept() 함수의 수행이 성공하면 접속된 클라이언트와의 통신에 사용할
새로운 소켓이 만들어지고 이 소켓번호가 리턴, 실패 시에는 -1이 리턴
서버는 이 클라이언트와 통신하기 위하여 accept()가 리턴한 새로 만들어진
소켓번호를 사용
서버는 *addr를 통해 클라이언트의 IP 주소를 알 수 있다
20
TCP Server Program (Cont’d)
 accept() 호출시 얻느 소켓주소 정보와 새로운 소켓
응용 프로그램(Client) socket()
bind()
listen()
accept()
새로운
소켓번호
소켓번호
1. 프로토콜
소켓 인터페이스
2. 자신의 IP 주소
3. 자신의 포트번호
4. 상대방 IP 주소
5. 상대방 포트번호
TCP/IP
네트워크
21
TCP Server Program (Cont’d)
22
프로그램 예제 확인 #4
 TCP Echo Server 프로그램
TCP 소켓을 이용하여 echo 서비스를 제공하는 서버 프로그램
프로그램은 클라이언트의 접속요청을 수락한 후 바로 echo 서비스를
수행한다.
이 서버를 이용할 클라이언트 프로그램은 예제 #2(tcp_echoli.c)를 사용
 프로그램 명: tcp_echoserv.c
23
UDP Program
 작성절차
Server
Client
socket()
socket()
bind()
데이터 송수신
recvfrom()
sendto()
sendto()
recvfrom()
종료
close()
24
UDP Program
 sendto()와 recvfrom() 함수의 사용법
25
프로그램 예제 확인 #5
 UDP Echo Client
socket(PF_INET, SOCK_DGRAM, 0)
….
sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, addrlen)
recvfrom(s, buf, MAXLINE, 0, (struct sockaddr *)&servaddr, &addrlen)
UDP를 이용하는 echo client 프로그램에서는 소켓을 UDP 타입으로
개설하는 부분과 echo server로 메시지를 보내고 받는 부분이 위와 같이
달라진다.
 프로그램 명 : udp_echocli.c
26
프로그램 예제 확인 #6
 UDP Echo Server
UDP Echo client 프로그램과 유사

UDP 통신 프로그램에서는 서버와 클라이언트의 구분이 없고 연결설정 과정도
없기 때문
주의



한쪽이 sendto()를 호출했으면 이 데이터를 받기 위해서 상대방은 반드시
recvfrom()을 호출해야 함
TCP 소켓에서는 스트림을 이용하므로 write()나 send()로 연속하여 쓰기를
수행하거나 read()나 recv()로 연속하여 읽기를 해도 문제가 되지 않음
UDP에서는 sendto() 와 recvfrom() 호출이 서로 짝을 이루도록 순서가 맞아야 함
 프로그램 명 : udp_echoserv.c
27
Connected UDP
 UDP 소켓을 통새서는 임의의 호스트와 통신을 할 수 있음
 UDP 소켓을 통해서 통신할 상대방이 한 곳으로 고정되어 있다면 처리
속도를 향상시키기 위하여 connected UDP를 사용할 수 있음
 connected UDP 소켓을 만들려면 일반 UDP 소켓에 대해 connect()
함수를 추가로 호출해 주면 된다
28
실습과제 #1
 daytime_tcp_server.c, daytime_tcp_client.c
Daytime service를 제공하는 서버 프로그램과 클라이언트 프로그램을
작성하시오.(TCP 이용)
Hint
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
Int main(int argc, char *argv[ ]) {
time_t tim;
tim =time(NULL);
printf(“현재 시각은 %s”, ctime(&tim));
return 0;
}
29
실습과제 #2
 daytime_udp_server.c, daytime_udp_client.c
Daytime service를 제공하는 서버 프로그램과 클라이언트 프로그램을
작성하시오.(UDP 이용)
Hint
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
Int main(int argc, char *argv[ ]) {
time_t tim;
tim =time(NULL);
printf(“현재 시각은 %s”, ctime(&tim));
return 0;
}
30
실습과제 #3
 hostname_tcp_server.c, hostname_tcp_client.c
 클라이언트가 도메인 네임을 서버로 전달해주면 그 서버의 hostname을
알려주는 프로그램을 작성하시오(TCP 이용)
 Hint
struct hostent, gethostbyname()
31
실습과제 #4
 hostname_udp_server.c, hostname_udp_client.c
 클라이언트가 도메인 네임을 서버로 전달해주면 그 서버의 hostname을
알려주는 프로그램을 작성하시오(UDP 이용)
 Hint
struct hostent, gethostbyname()
32