오큘러스에서 회전값을 받아와 UDP로 뿌려주면 로봇에 달려있는 PC가 시리얼포트로 로봇 목을 제어하는 모듈을 개발중이다.
UDP는 이번에 처음 사용해보는데 TCP에 비해 프로토콜이 굉장히 간단한 느낌이다.
UDP가 TCP에 비해 빠르다고 하는데 내가 만든 것은 가벼운 프로그램이라 체감은 못하겠고 TCP와 다른점은 다음과 같다.
1. UDP는 클라이언트 접속 개념이 없고 데이터 검증이 없다.
TCP는 서버가 클라이언트를 listen하면 클라이언트가 접속을 시도하고 접속이 됐다는 결과를 알려준다. 접속 종료시에도 마찬가지이다.
하지만 UDP는 특정 port로 열어둘테니 데이터를 던져봐라라는 느낌이다. 데이터가 어느 클라이언트에서 왔는지는 알아서 판단해야한다.
TCP 데이터 송수신은 데이터를 보내면 받았다는 것을 확인하는 작업이 존재하며 데이터가 손실 됐을 시 데이터를 재 요청한다. 따라서 손실이 없다.
UDP는 이런 작업이 없으며 손실 여부도 데이터를 받는 쪽이 확인해야한다.
[그림1 TCP 헤더]
(출처: 위키피디아)
위의 그림1은 TCP 헤더를 나타낸다. 헤더만 거의 20바이트인데 이것을 통해 데이터 검증, 순서 등을 확인한다.
아래 자세히에 헤더의 각 필드 당 설명이 적혀있다.
Source port (16 비트)
송신 포트
Destination port (16 비트)
수신 포트
Sequence number (32 비트)
SYN 플래그가 (1)로 설정된 경우, 이것은 초기 시퀀스 번호가 된다. 실제 데이터의 최초 바이트 값과 그에 상응하는 ACK 번호는 이 값에 1을 더한 값이 된다.
SYN 플래그가 (0)으로 해제된 경우, 이것은 현재 세션의 이 세그먼트 데이터의 최초 바이트 값의 누적 시퀀스 번호이다.
Acknowledgment number (32 비트)
ACK 플래그가 설정된 경우 이 필드의 값은 수신자가 예상하는 다음 시퀀스 번호이다. 이것은 모든 선행하는 바이트들(존재할 경우)에 대한 수신에 대한 확인응답이 된다. 한쪽이 보낸 최초의 ACK는 반대쪽의 초기 시퀀스 번호 자체에 대한 확인응답이 되며, 데이터에 대한 응답은 포함되지 않는다.
Data offset (4 비트)
32-bit 워드 단위로 나타낸 TCP 헤더 크기값이다. 헤더의 최소 크기는 5 워드이며 최대 크기는 15 워드이다. 따라서 최솟값은 20바이트, 최댓값은 60바이트가 되며, 헤더에 선택 값을을 위해 최대 40 바이트가 더 추가될 수 있다. 데이터 오프셋이라는 명칭은 이것이 실제 데이터 상에서의 TCP 세그먼트의 시작 위치의 오프셋이기 때문에 붙여졌다.
Reserved (3 비트)
미래에 사용하기 위해 남겨둔 예비 필드이며 0으로 채워져야 한다.
Flags (9 bits) (혹은 Control bits)
9개의 1-비트 플래그를 포함
NS (1 비트) – ECN-nonce 은폐 보호(RFC 3540에 의해 헤더에 추가).
CWR (1 비트) – 혼잡 윈도 축소(Congestion Window Reduced) 플래그는 송신측 호스트에 의해 설정되는 것으로, 호스트가 ECE 플래그가 포함된 TCP 세그먼트를 수신했으며 혼잡 제어 메커니즘에 의해 응답했음을 알리는 역할을 한다(RFC 3168에 의해 헤더에 추가).
ECE (1 비트) – ECN-Echo는 다음을 나타낸다.
SYN 플래그가 (1)로 설정된 경우, TCP 상대가 명시적 혼잡 통지(Explicit Congestion Notification, ECN)가 가능함을 의미한다.
SYN 플래그가 (0)으로 해제된 경우, IP 헤더 셋에 혼잡 경험(Congestion Experienced) 플래그가 설정된 패킷이 정상적인 전송 중에 수신되었다는 것을 의미한다(RFC 3168에 의해 헤더에 추가).
URG (1 비트) – Urgent pointer 필드의 값이 유효함을 나타낸다.
ACK (1 비트) – Acknowledgment 필드의 값이 유효함을 나타낸다. 클라이언트가 보낸 최초의 SYN 패킷 이후에 전송되는 모든 패킷은 이 플래그가 설정되어 있어야 한다.
PSH (1 비트) – 푸시 기능. 수신 애플리케이션에 버퍼링된 데이터를 푸시해 줄지 여부를 질의하는 역할을 한다.
RST (1 비트) – 커넥션 리셋
SYN (1 비트) – 동기화 시퀀스 번호. 양쪽이 보낸 최초의 패킷에만 이 플래그가 설정되어 있어야 한다. 다른 일부 플래그들의 의미가 이 플래그의 값에 따라 바뀌며, 일부 플래그들은 이 플래그가 설정되어 있을 때만 유효하고, 또 다른 일부 플래그들은 이 플래그가 해제되어 있을 때에만 유효하다.
FIN (1 비트) – 남은 송신측 데이터 없음
Window size (16 비트)
수신 윈도의 크기. 해당 세그먼트의 송신측이 현재 수신하고자 하는 윈도 크기(기본 단위는 바이트). acknowledgment 필드의 시퀀스 번호보다 큰 값이어야 한다.
Checksum (16 비트)
헤더 및 데이터의 에러 확인을 위해 사용되는 16 비트 체크섬 필드
Urgent pointer (16 비트)
URG 플래그가 설정된 경우, 이 16 비트 필드는 시퀀스 번호로부터의 오프셋을 나타낸다. 이 오프셋이 마지막 긴급 데이터 바이트를 가리킨다.
Options (가변 0–320 비트, 32의 배수)
이 필드의 길이는 데이터 오프셋 필드에 의해 결정된다. 이 부분은 Option-Kind (1 바이트), Option-Length (1 바이트), Option-Data (가변) 이렇게 최대 3개의 필드로 구성될 수 있다. Option-Kind 필드는 옵션의 종류를 나타내며, 세 가지 필드 중 유일하게 필수값이다. 옵션의 종류에 따라 나머지 두 개의 필드가 설정될 수 있다. Option-Length 필드는 옵션의 전체 길이를 나타내며, Option-Data 필드는 적용 가능한 경우 해당 옵션의 값을 나타낸다. 예를 들어, Option-Kind 바이트 값이 0x01인 경우 이는 패딩의 용도로만 사용되는 옵션없음(No-Op) 옵션을 의미하며, 이 때에는 뒤따라 오는 Option-Length나 Option-Data 값이 존재하지 않는다. Option-Kind 바이트 값이 0인 경우 이는 옵션종료(End Of Options) 옵션을 의미하며, 전자와 마찬가지로 뒤따라 오는 추가 옵션 필드가 없다. Option-Kind 바이트 값이 0x02인 경우 이것은 최대 세그먼트 크기(Maximum Segment Size) 옵션을 의미하며, 그 뒤에는 MSS 필드의 길이값(0x04여야 함)이 따라오게 된다. 이 길이값은 Option-Kind와 Option-Length를 포함한 주어진 옵션 필드의 전체의 길이를 나타내는 것이다. 따라서 MSS 값은 일반적으로 2 바이트로 표현되며, 해당 필드의 길이는 4 바이트(kind와 length의 2바이트를 더한 값)가 된다. 실제 예를 들어 설명하면, 0x05B4라는 값을 갖는 MSS 옵션 필드는 (0x02 0x04 0x05B4)의 형태로 TCP 옵션 섹션에 나타날 것이다.
일부 옵션은 SYN 플래그가 설정되어 있을 때에만 송신된다. 이러한 옵션은 아래에 [SYN]으로 표시되어 있다. Option-Kind 및 기본 Option-Length는 (Option-Kind, Option-Length)으로 표시되었다.
0 (8 비트) – End of options list
1 (8 비트) – No operation (NOP, Padding) 이것은 속도 향상을 위해 옵션 필드를 32 비트 길이에 맞추기 위해 사용될 수 있다.
2,4,SS (32 비트) – Maximum segment size (최대 세그먼트 크기 참조) [SYN]
5,N,BBBB,EEEE,... (variable bits, N is either 10, 18, 26, or 34)- Selective ACKnowledgement (SACK)[7] 이 첫 2 바이트 뒤에는 선택적 확인응답을 받는 1-4개 블럭의 리스트가 따라오게 되며, 이들은 32 비트 시작/종료 포인터로 구분된다.
8,10,TTTT,EEEE (80 비트)- Timestamp and echo of previous timestamp (see TCP 타임스탬프 참조)[8]