Computer Science/Network
application layer
Prower
2022. 12. 22. 17:53
728x90
반응형
1. application layer
- 실제 컴퓨터에서 작동하는 프로세스가 속한 계층
- 네트워크는 다른 컴퓨터의 프로세스간 통신
- 클라이언트 - 서버의 프로세스간 통신
- socket: 통신을 위한 interface. 프로세스가 OS에 네트워크 통신을 요청할 때 사용하는 interface
- IP: 네트워크상 host 연결을 위한 주소. host를 식별하는데 사용
- port: 프로세스의 socket 연결을 위한 주소. host의 프로세스를 식별하는데 사용
socket
- 프로세스는 소켓을 통해 통신한다.
- application layer에서 transport layer에서 제공하는 소켓에 의존한다.
- 소켓은 process에서 전달하는, process로 전달되는 데이터 제어
transport layer에 대한 요구
application layer는 transport layer에서 제공하는 기능, 서비스를 사용함
제공하는 기능에 대한 요구는 다음과 같을 수 있으나 실제로 application layer는 데이터 안정성만 제공한다.
- 데이터 안정성: 데이터가 유실되지 않고 목적지에 도달함 -> TCP가 제공
- 시간 제약 -> 제공 X
- 스루풋 -> 제공 X
- 보안 -> 제공 X
2. client - server 구조
server
- 고정된 IP와 port를 가진다.
- 고정된 포트를 사용 이유(e.g http는 80번 사용)
- 일종의 약속이나, 일정한 IP를 유지하는 이유와 같음
- 서버 프로세스의 포트가 변경되면 클라이언트가 서버의 프로세스를 찾아갈 수 없다.
- 고정된 포트를 사용 이유(e.g http는 80번 사용)
- host의 요청을 기다림
client
- 서버와 통신
- 변경이 가능한 IP, port를 사용
3. HyperText Transfer Protocol
- hypertext를 전달하는 프로토콜
- 클라이언트가 요청하고자 하는 url로 리소스를 요청
- 웹 서비스가 http 위에서 동작하는 구조
- client: send HTTP request
- server: send HTTP response
transport layer
- TCP를 사용하기 때문에 request, response 이전에 TCP connection 필요
연결 단계
- 서버가 TCP 소켓 개방
- 클라이언트가 TCP 연결 요청
- 서버가 클라이언트의 TCP 연결 요청 accept
- HTTP 메세지 전송
- TCP 연결 close
stateless
- 서버에서 client의 상태를 기록하지 않음
persistent vs non-persistent
- HTTP 통신은 한번의 TCP 연결에 하나의 object(hypertext, jpg...)를 전송
- 여러 object를 받기 위해서 여러번의 TCP 연결이 필요하며 이는 비효율적
- persistent: 한번의 TCP 연결로 여러 객체를 전달하는 방식
- non-persistent: 한번의 TCP 연결 마다 하나의 object 전송
- 동작 방식
- try TCP connection
- http request, response
- close TCP connection
- client parses hypertext
- need more hypertext
- start from 1. ...
- 그러나 이는 비효율적이므로 HTTP/1.1 에서는 pipelining 방식을 통해 response를 기다리지 않고 여러개의 request를 보내고 many response를 받는 방식으로 작동한다.
- 동작 방식
response time
- RTT: 클라이언트에서 전송된 패킷이 서버에 도달하여 다시 돌아오기 까지의 시간
non-persistent 연결 구조
(non-) persistent 모두 요청을 위한 RTT가 한 번 필요하고, 이후 object를 전달받는데 RTT + file transmission time이 소요된다.
- non-persistent의 경우 n개의 object를 받는데: (2 * RTT + file transmission time) * object 수 가 소요된다.
- persistent의 경우 한번의 n개의 object를 받는데: RTT + (RTT + file transmission time) * object 수 가 소요된다.
4. socket
- 네트워크를 위해 OS에서 제공하는 interface
- application layer는 transport layer에서 제공하는 interface 사용
- 어플리케이션은 네트워크 통신을 위해
- TCP, UDP에 맞는 소켓을 생성
- 소켓을 통해 데이터를 전송하고 받는다
- 종류: TCP(SOCK_STREAM), UDP(SOCK_DGRAM) 소켓
API
동작 구조
- 연결 준비
- server
- socket(): 소켓 생성
- domain(IP), type(TCP, UDP), protocol을 인자로 받음
- 생성된 소켓 번호(file descriptor) 반환
- bind(): 소켓을 특정 port에 바인딩
- socket()에서 생성된 file descriptor, 서버의 IP/port, 주소 길이를 인자로 받음
- listen(): 클라이언트의 요청을 대기
- file descriptor, backlog(connection queue 길이)를 인자로 받음
- accept(): 연결을 받을 준비 완료
- file descriptor, 요청으로 들어온 클라이언트의 IP/port, 주소 길이를 인자로 받음
- 클라이언트의 연결이 들어올 때 까지 blocking
- socket(): 소켓 생성
- client
- connect(): 서버에 연결
- 클라이언트의 소켓 번호, 서버의 IP/port, 주소 길이를 인자로 받음
- connect(): 서버에 연결
- server
- 데이터 전달
- read(), write(): 연결 이후 데이터를 주고 받기 위한 API
- 연결 종료
- close(): 연결이 끝난 뒤 소켓을 닫고, 점유했던 port를 반납한다.
예시 코드
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
void cleanExit(){exit(0);}
#define PORT 7777
#define BACKLOG 10
int main(void) {
signal(SIGTERM, cleanExit);
signal(SIGINT, cleanExit);
int sockfd, new_fd;
struct sockaddr_in source_ip;
struct sockaddr_in dest_ip;
int sin_size;
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
source_ip.sin_family = AF_INET;
source_ip.sin_port = htons(PORT);
source_ip.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr *) &source_ip, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr*) &dest_ip, (socklen_t*)&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got conection from %s\n", inet_ntoa(dest_ip.sin_addr));
char result[] = "hello world\n";
write(new_fd, result, sizeof(result));
close(new_fd);
}
}
해당 서버를 실행하고 netcat을 통해 localhost:9898(IP:port) 로 요청하면 리턴값을 받을 수 있다.
반환
> nc localhost 9898
> hello world
728x90
반응형