Post

7. Socket

Socket Programming

Socket: 소켓은 process와 process가 통신하는 end-to-end protocol의 door.

여기서 CPU는 process와 OS를 왔다갔다하며 1 - by - 1 visit을 한다. 즉 매번 네트워크 패킷이 도착했는지 boucing을 하며 체크를 해줘야한다는 것이다.

→ 이 bouncing으로 인해 CPU 성능상의 upperbound가 생긴다. 어떻게 하면 최대속도를 낼 수 있을까?

  1. Dedicate one core in CPU

  2. Network hardware

  3. User space에서 application이 하도록 하자. (ex. cloud computing)

    1. kernel bypass technique
    2. 메모리를 왔다갔다 하는 것이 매우 손해이기 때문에, buffer를 많이 크게 만들자.

    → 이렇게 되면 패킷 단위에서는 느려지지만 throughput이 증가한다.

  4. kernel에서 다하게 되면 app까지 안가도 되어서 latency가 줄어든다.

Socket programming에는 2가지 방식이 있다.

  1. UDP: unreliable datagram
  2. TCP: reliable, byte stream oriented.
    1. socket buffer에 패킷을 저장한 다음에, reliable한 order data로 만들어준 후 app으로 올리기 때문에 app 입장에서는 매우 느리다.

UDP

udp는 connection이 없다.

  • no handshaking before sending data
  • sender explicitly attaches IP address and port #, to each packet
  • receiver extracts sender IP address

→ 순서가 뒤바뀔 수 있고, lost될 수 있다.

UDP는 reliable하지 않다. 하지만, n개의 sender에서 한번에 패킷을 받을 수 있다. (useful in P2P!)

반면, TCP는 connection으로 인해 매번 IP주소를 적을 필요가 없다. 단, 1 ACK에 1 RTT가 걸린다.


작동 방식의 차이

  • UDP는 ip 주소 붙이고 일단 보냄, datagram 주고 받음
  • TCP는 먼저 서버와 contact를 한다.
    • socket을 만들고
    • 서버와 클라이언트의 socket이 서로 연결된다.
      • 서버는 여러 클라를 위해 여러개의 소켓을 만든다.

→ 앱 입장에서는 (virtually) reliable한 연결을 만들어준다.


Latency from socket

Application → socket() → sk_buffer → TCP (Congestion Control Algorithm) → Network device

App에서 buffer로 들어가는 시간 : F(t) → app에 따라 다름

buffer에서 network drive로 들어가는 시간: R(t) → transmit가 끝난 이후에 읽어야하기 때문에 거의 고정됨

따라서 조정할 것은 buffer size임

(1) large: Latency가 증가함.

(2) small: 한번에 조금조금밖에 못보내게 되기 때문에 bitrate가 감소함.

→ Game development: The data has small size (some commands), so F(t) is relatively smaller than R(t). buffer size should be large?

→ zoom : adjust F(t) by R(t) (network)


OS를 매번 거쳐서 네트워크 통신을 처리하면 bouncing 때문에 너무 오래걸린다.

→ priority를 올릴까? 그래도 100% occupy하지는 못한다. 이것이 다 fairness에 대한 문제로 귀결된다.


Transport Layer

그래서 transport layer가 무엇인가.

  • provide logical communication between app processes

  • runs in end systems

    • break message into segments → 너무 작으면 header 붙이고 떼는 비용이 너무 많이 듦. → 너무 크면 error correction에 불리함. checksum으로는 무슨 패킷이 문제인지 모름. retransmission이 발생할 확률도 큼.
      • In analog, there are some bit-switching(flipping) which makes checksum hard to detect error. So, we have to choose appropriate size of packet.
      • Lossy channel → small packet size is useful for error correction!
    • reassembles segments

Network Layer와 뭐가 다른거지?

  • Transport : logical communication between processes
  • Network : logical communication between hosts

편지를 다른 집 아이들에게 보내는 비유를 생각해보면…

transport는 받은 편지를 아이들에게 나눠주는(demux) 부모님들이고

network는 postal service인 것이다.


Multiplexing / Demultiplexing

(1) Multiplexing: 여러 socket에서 받은 데이터를 handle하고, transport header를 붙인다.

(2) Demultiplexing: 받은 여러 데이터으 header를 분석하여 원하는 socket으로 보낸다.

매번 socket으로 데이터를 decode해서 보내야하기 떄문에 에너지 소모가 매우 크다.

→ 즉, sleep이 필요하다.

sender 입장에서는 socket buffer에 패킷이 있을 때 awake하면 된다!

receiver는 100ms마다 wifi로 check하면 될 것이다.


Connectionless demux

같은 ip주소와 port 넘버가 온다면, socket으로 바로바로 보낸다.

즉, 여러 곳에서 온 패킷들이 동시에 마구잡이로 들어올 수 있다.

ex) Youtube에서는 모두 connect해버리면 메모리 오버헤드가 발생한다.

즉, connectionless하게 짜야한다.

→ TCP와 UDP 모두 장단점이 있으니 앱 개발할 때는 적절한 것을 선택해야한다.


Connection-oriented demux

TCP의 소켓은 4개의 tuple로 정의된다. 수신자, 송신자 각각의 ip와 port number

즉, 송신자가 다르면 socket이 다르다. 이것을 여러개의 process로 돌릴 수도 있지만,

보통 threaded server로 처리한다.


UDP usage

  • no frills, bare bones (진짜 뼈대라서 필수적인 역할만 수행한다)
  • best effort service, but may be lost or out-of-order
  • connectionless
    • no handshaking
    • each UDP handled independently
    • smaller header size!
  • No Congestion Control → Max data rate
  • Used in…
    • Streaming multimedia → loss tolerant and rate sensitive
    • DNS server → user can easily refresh. Loss is not critical
    • SNMP → It exchanges every several minutes

그래도 reliable 해지고 싶다면… → app에서 실행할 것. app에서 recovery할 것!

UDP에는 error를 고치지는 않지만 checksum으로 detect는 할 수 있다.

→ flip 이 2번 발생하면 잡을 수 없음.


Checksum in UDP

모든 16비트를 더한다.

모든 것을 16비트(1 word)로 하여 더하고, carry된 비트를 다시 더해준다.

그 후 1의 보수를 취하여 checksum을 만든다.

→ 해당값을 수신자측에서도 동일하게 적용하여 값을 비교한다.

The Internet checksum will not detect the error?

In which cases, the TCP checksum will not detect an error?

→ 모든 데이터를 16비트로 잘라서 더하기 때문에, 16비트 단위로 값이 서로 flipped되면 checksum은 같아진다.

This post is licensed under CC BY 4.0 by the author.