Hi there!

I am a student studying computer science.

시스템 프로그래밍

시스템 프로그래밍 13장 - Network

만능성구 2020. 6. 18. 12:15
728x90

Network Protocols for Communications

PC와 PC 사이에 network 통신을 통해서 data를 주고 받는 program에서는 통신 위한 protocol을 이해해야한다.

 

Protocol

- error를 발생시키는 data link들 간에 error-free를 위한 사전 정의 된 통신 단계.
- 일반적으로 Protocol은 multiple-layerd로 구현됩니다.

왜?

- error-free 목적달성을 위해
- 너무 크다.
– 다양한 abstraction추상화 수준
– 다양한 service서비스 수준
– 다양한 media미디어 및 communications types 통신 유형

에 따른 network 통신을 보장 하도록


Network 표준 OSI 7 layers (OSI reference model)

Physical layer : electrical signaling system, (wired, wireless)

Data link layer : error free communications between adjacent nodes;

– MAC layer (Medium Access Control) : multiple shared accesses to a link/bus (ethernet, RF)

– Point-to-point (a private link between nodes)

-------------------------------------------------------------------HW기반

Network layer : Routing (which must be the next node to deliver the received packet to the final target?), IP in the Internet Protocol

Transport layer : host APIs for end-to-end communications

TCP/UDP in the Internet Protocol • Session layer : session management, error recovery

Presentation layer : Encryption/decryption, network standard data format, other libraries/utilities (address translation, etc.)

Application layer : ftp, email, rlogin, telnet, web server/browser (http), etc

-------------------------------------------------------------------SW기반


- 사용자 processor의 message를 여러개로 나누어서 전송한다.

각 protocol layer의 segments (Fragmentation)

- 사용자의 message는 각 protocol layer의 segments로 merge될 수 있다.

- 각 layer는 layer의 packet header를 segment에 붙인다. -> packet frame.

 z.B.) TCP segment : TCP Header + Data segment

       IP header + TCP segment + CRC checksum

         ....

       각 layer는 MTU(Maximum Transfer Unit)을 가진다 :  각 layer에서 최대 size의 data segment

하나의 message를 만들어서 전송하는데 layer를 통과할 때마다 해당 layer의 packet header를 붙여서 전송하고 다음 layer에서 header를 해석하여 전송한다. 이렇게 layer간 통신을 한다. 

 

일반적으로 모든 layer를 구현하지 않고 몇 개로 묶어서 구현해놓는다.

 

Examples

Linux는 위의 4개의 Layer로 묶어서 구현한다.

아래 3개는 kernel에서 application layer는 user level에서 동작한다.

application layer : + http

Network layer : IP protocol serverse

Data Link layer : physical한 hardware

 

그 이외의 Network protocol

ICMP(Internet Control Message Protoco) : ping이 살아있느지

IGMP(Internet Group Message Protocol) : router protocol, 아래부터 network layer까지만 사용해서 가능

 

Layer 구조적 도식화

ARP (Address Resolution Protocol): IP -> physical MAC address

RARP (Reverse Address Resolution Protocol) : physical MAC address -> IP


User level application layer에서 직접 interfacing하는 system level protocol은 TCP / UDP

대부분 TCP를 사용해서 구현한다.


network을 통해서 data를 전송하는 것은 두 PC간 가상의 선을 연결을 시켜놓고 가상의 선을 통해서 연결하는 것

TYPE

• Client / Server  : client program ↔ server program

• Web-based : web-browser(client) ↔ web-server(server)

• Peer-to-Peer(P2P) : 자신이 server가 될 수 있고 client가 될 수 있는

Client / Server

- 두 개의 processes가 모두 필요하다.

- protocol API가 갖추어져서 둘간의 connection을 맺고 data를 주고받는다.

- connection을 할 때는 network layer를 기반으로 그중 IP address, port기반의 protocol로 통신한다.

- packet방식으로 전송한다.

- 일반적으로 socket을 이용해서 connection을 한다.

 

Server :  불특정 다수의 연결을 waiting하고 있는 것

- client connection을 기다리다가 connection이 오면 client에게 제공하기 위해 처리할 child(thread)를 생성해서 data를 주고 받는다.

- 다수의 client에 대해 처리할 수 있도록한다.

- port와 IP address를 가지고 있는 상태에서 running, waiting을 하고 있다.

 

Client : 직접 대상이 되는 computing machine에 접속을 하고 data를 요청하는 것

- client는 하나의 connection만 유지하면 된다.

- server의 IP address와 port 번호를 이용해서 connection을 시도한다.

 

각자의 하부의 layer를 거쳐서 실제 physical Internet을 겨쳐서 전송한다. : end-to-end communication

 

connection을 유지하고 있는 방식과 conneciton이 없이 data를 보낼 때 destination 대상에 data를 보내는 방식

Connection-oriented

Use the TCP (Transmission Control Protocol) protocol,

- 안정적인 data전송을 보장한다.

- 각각의 client에게 connetion에 대한 link를 만들어야한다.

- client가 많아지면 overhead가 될 수 있다.

Think telephone communications! (Virtual Circuit)

 

Connection-less

Use the UDP (User Datagram Protocol) protocol,

- packet의 해당 destination 정보만을 가지고 data를 전송하므로 link를 유지하지 않을 체 data가 그 순간의 packet의 정보를 가지고 전송한다.

- single message transmission에 적절하고

- No link for clients이기 때문에 client가 많아도 overhead가 없다

- 대신에 reliable(안정적인) data전송을 보장하지 않는다.

- Can be used for broadcast or multicast services.

Think datagram of post offices!


Server Types

sever는 다수의 client에 대해서 하나의 server가 service를 제공하므로 수많은 client에 응답해야한다.

 

Repetitive server type (singlethreaded server)

하나의 server의 thread가 다수의 thread를 동시에 support하는 방식

- server가 단순해 진다.

- 문제 발생 적어진다.

- 응답이 느려진다

 

Concurrent server type (multithreaded server)

여러 개의 therad를 만들어서 각 thread가 client를 응대하는 방식

- 성능은 좋지만

- 문제점이 발생될 여지가 있다

- 서버가 복잡해진다.

Concurrency problems (e.g. Mutex)


/*Network protocol layer 별로 각 layer, protocol이 제공하는 protocol interface,

즉 자신들의 기능을 제공하는 api들을 각 protocol은 제공하고 있다.

그 network protocol을 사용하는 대상이 되는  application, 상위 하위 레벨의 layer들은 protocol이 제공하는 api이용해서  protocol과 연동을 할 수 있다.

ex)

Device driver layer에 있는 것들은 어떤 device funtion들 interface를 이용해서 각 network layer, Transport layer는 각 device에서 제공해주는 api를 이용해서 자신의 protocol을 suppeor할 수 있게 만들어야한다.

tcp / udp는 여기까지 system layer 대체적으로 socket을 이용한다. window - winsock, linux - socket

해당 하부 network protocol을 사용한다. 그렇게 제공하는 api도 각 기능을 제공하기 위해 protocol기반을 구현한다.

웹 브라우저 기반 server는 http, 파일전송기반은 ftp, 이메일은 email들을 이용해서 protocol을 이용한다.

transport. 각 interface를 이용해서 자신들의 system을 이용한다.,*/ 뭔소리하는지 하나도 모르겠음 내 맘데로 정리할 꺼 ㅗㅗ

Programs/APIs of Each Layer

앞에서 하던말이랑 똑같은 거 같음

아래부터 Transport까지가 kernel이 동작시키는 system layer, 그 위로는 user가 제어하는 layer

각 층마다 protocol이 있고 서로 통신하기 위해서 서로의 interface를 이용해서 연동되어야햔다. systsem들은 지들 알아서 하겠지만 보통 socket을 이용한다. 

아 몰라~


TCP, UDP를 이용한 Socket Communications

각각의 process간 연결을 구분하기 위해 IP와 port #로 구분한다.

 

TCP는 (IP address와 port#)를 묶어서 이용

Stream I/O : Server와 Client간의 socket끼리 binding 시킨다(하나의 link를 만든다.)

link끼리 data를 전송하기 때문에 reliable(안정적), data의 flow control(복잡 제어?) , error가 발생 시 재시도하는 error contorol 기법이 들어가 있다.

 

UDP는 process socket들 간의 IP와 port#를 이용하지만 매번 IP와 port#를 만들어서 전송한다.

한번에 작은 data를 전송하는데 유용하다.

data 전송을 unreliable하고 network 순서가 바뀔 수 도 있다.

error control 기능을 제공하지 않는다, 

그래도 overhead를 발생시키지 않는다


앞에서 TCP든 UDP든 socket을 지정할 때 IP+port#를 이용하는데 port#가 application program으로 구분해서 띄운다.

 

일반적으로 많은 protocol들이 자신의 port#를 가진다

DNS : 23, TFTP : 69, 텔렙 : 21, ssh : 22

그 이외의 port는 자신이 할당해서 사용할 수 있다. (0 ~ 65535)

 

TCP방식을 이용한 client server간의 통신을 도식화

server는 IP+port를 binding해서 socket을 만들어서 listen을 하고 있다.

client는 해당 IP+port를 이용해서 socket을 만들어서 접속을 시도하고(connect())

접속을 이루어지면 서버에서 (accept())하게 되고 이후엔 동등한 상태로  send()와 recv()할 수 있다

더 이상 통신할 것이 없으면 close()로 socket을 종료

 

UDP방식을 이용한 client server간의 통신을 도식화

server는 IP+port로 socket을 만들어서 binding시켜서 socket을 open상태로 만든다.

server는 listen하고 있지 않다. client는 connect을 시도하고 연결을 확인만 한다.

client는 sendto로 요청을 하고 server는 rectform으로 받는다. 반대도 마찬가지

연결을 끊을 필요가 없다.


socket address structure

#include <sys/socket.h>
struct sockaddr {
  u_char sa_len; /* address structure length */
  u_char sa_family /* address type */
  char sa_data[14]; /* 14 byte-address */
};
모든 Type에 적용가능한 구조체
#include <netinet/in.h>
#include <sys/types.h>
// sockaddr internet (practical address structure used by internet TCP/UDP)
// when use this structure in relevant syscalls, address casting to sockaddr is needed
struct sockaddr_in {
  u_char sin_len; // address structure length
  u_char sin_family; // address type
  u_short sin_port; // 16 bit port #
  struct in_addr sin_addr // 32 bit IP address
  char sin_zero[8]; // not used, for the further use: must set to be all zeros
};

struct in_addr
{
  u_long s_addr; // 32 bit IP address
}
Internet을 위한 구조체
TCP / UDP를 하는데 필요

sin_family:

AF_INET: internet IP address                            //sockaddr_in 사용

AF_UNIX: UNIX or used for local communications //sockaddr 사용

– The server & client are all in the local host,

– But use the whole protocol stack.

– Usually be used for testing

• AF_NS: XEROX network address


#include <sys/socket.h>
#include <sys/types.h>
int socket (int domain, int type, int protocol);
socket을 생성해주는 system call
input
   - domain : address types
      • PF_INET: internet protocol
      • PF_INET6: IPv6 protocol
      • PF_UNIX: UNIX, local communications
      • PF_NS: XEROX: Xerox network address
      • PF_IMPLINK: IMP link layer address
   - type : socket type

   - protocol : protocol for use 

         (packet header format) //default값으로 지정
return socket id(descriptor) / -1
#include <sys/socket.h>
#include <sys/types.h>
int bind (int sockfd, struct sockaddr *myaddr, int addrlen);
socket에 대해서 user application IP+port#을 bind해주는 system call
input 
     - sockfd : socket descriptor (file descriptor) 
     - myaddr : address of the socket address structure // internet을 쓸 경우 sockaddr_in을 쓴다
     - addrlen : size of the “myaddr” structure 
return 0 / -1
#include <sys/socket.h>
#include <sys/types.h>
int connect (int sockfd, struct sockaddr *servaddr, int addrlen);
client에서는 socket생성 후 접속을 시도할 때 사용
socket id에서 binding같은 작업을 하고 connection을 시도하므로 auto-binding이 이루어진다, 
client에서는 binding필요없다.
input:  // bind와 동일
     - sockfd : socket descriptor
     - myaddr : socket addr. structure that contains the IP & port of the server.
     - addrlen : size of the “servaddr” structure
 return 0 / -1
#include <sys/socket.h>
#include <sys/types.h>
int listen (int socket, int queuesize);
server에서 받는거 시도
input 
     - socket : bound socket descriptor 
     - queuesize : max. number of client connection requests 
return 0 / -1
#include <sys/socket.h>
#include <sys/types.h>
int accept (int sockfd, struct sockaddr *peer, int *addrlen);
client의 request를 받을 준비가 되었다. client의 connection request를 기다린다.
block wait상태가 된다.
new sockey descriptor를 받는다.
이전 socket은 추가 연결을위한 다른 client request에 사용됩니다.
input:
     - sockfd : socket descriptor
     - peer : the socket address structure that contains the IP & port of the connected client  // clinet의 address정보
     - addrlen : size of the “peer” structure
return  a new socket descriptor to communicate the client / -1
#include <sys/socket.h>
#include <sys/types.h>
int send (int sockfd, char * buf, int bytes, int flag);
*TCP* data전송을 할 준비가 된 상태에서 data전송을 주고 받기 위해 TCP경우 send로 data를 보낸다
server, client둘다 보낼 수 있다.
input
     - sockfd : socket descriptor
     - buf : data buffer holding the data to be sent
     - bytes : size of the buffer
     - flag : options
            » MSG_OOB: OOB(out of bound) data: used for urgent data sending
            » MSG_PEEK: keep the data in the buffer
            » MSG_DONTROUTE: ignore the usual routing
return the size of the data that actually be sent / -1

TCP경우 data를 보내는 것은 Stream I/O로 connection된 상태에서 한쪽에서 다른쪽으로 data를 보낸다.

 

- send()를 완료한 것은 sender's protocol buffer에 성공적으로 store한 것이다.

- *client까지 전송된 것이 아닐 수도 있다.

- reciver가 ACK를 전송하면 성공된 것이고 seder's buffer를 지운다.

- 전송에 실패(time out)하여 reciver에서  NACK를 전송하면 sender는 재전송한다.

 : reliable한 통신이다. user가 TCP layer에 쓰면 전송을 보장 받는다

- TCP stream I/O는 message를 split/merger해서 전송할 수 있다. 

 : 이때 header/length로 buffering을 이용해서 처리한다.

#include <sys/socket.h>
#include <sys/types.h>
int recv (int sockfd, char * buf, int bytes, int flag);
*TCP* data를 수신하는 system call
sender에서 data가 오도록 block하는 상태
input
     - sockfd : socket descriptor
     - buf : user’s receive-buffer
     - bytes : 받을 공간의 크기
     - flag : options (maybe NULL)
return 받은 data크기(최대 bytes) / -1
#include <sys/socket.h>
#include <sys/types.h>
int sendto (int sockfd, char * buf, int bytes, int flag, struct sockaddr *to, int addrlen);
*UDP* data 송신
input:
     - sockfd : scoket descriptor
     - buf : buffer address
     - bytes : size of the buffer
     - flag : options
     - to : socket adddress에 대한 주소
     - addrlen : address의 크기
return 보낸 data의 크기 / -1
#include <sys/socket.h>
#include <sys/types.h>
int recvfrom (int sockfd, char * buf, int bytes, int flag, struct sockaddr *from, int *addrlen);
*UDP* data 수신
block상태가 된다.
input
     - sockfd : socket descriptor
     - buf : buffer for data reception
     - bytes : size of the buffer
     - flag : options
     - from : sender’s address structure
     - addrlen : size of the “from” structure
return 받은 data 크기 / -1
#include <unistd.h>
int close (int sockfd);
생선된 socket을 종료하고 tcp의 경우 link를 끊는다. 닫고 제거
input
     - sockfd : socket descriptor
return 0 / -1

client.c

server.c


TCP Issue

1kb 문장 단위보다 큰 data를 보낼경우 하나의 message가 아닌 split해서 여러 message로 보낸다.

이것을 다 받을 수 있도록 보장할 필요가 있다.

방법1

다 받을 때까지 recv()를 호출한다. 

마지막 flag가 0이아닌 MSG_PEEK하고 다 끝나면 해제해라.

방법2

크기를 정확히 알면 buffer를 이동시키면서 자신의 user buffer에 저장한다.

Data Format Conversion Issue

다른 data형식을 주고 받을 때

network 상에서 고려하지 않아도 되도록 network format으로 conversion한다.

htonl(host to newtork)

Little endian vs big endian 이 달라서 맞춰야됌

bit형식으로 data연산에 사용

 

integer이나 short에 대해서는 위에 것들을 사용하면 해결되지만 

float이나 double에 대해서는 user가 알아서 해줘야한다.

 

728x90