'HTTP'에 해당되는 글 3건

  1. 2016.07.06 [HTTP2.0] DATA 프레임
  2. 2016.06.30 웹소켓 프레임 구조
  3. 2016.06.28 [HTTP] 웹소켓 핸드쉐이킹 (2)

6.1.  DATA

DATA 프레임(type=0x0)은 가변 길이의 유저 데이터를 전송하는 역할을 담당합니다. (Http의 리퀘스트나 리스폰스의 페이로드 등).
한번의 요청이나 응답에 대해서 DATA프레임은 여러번 전송될 수 있습니다.


또한 DATA프레임에는 패딩이 붙을 수 있습니다. 패딩은 DATA 프레임 끝에 추가되어 전체 데이터의 크기가 얼마나 되는지 예측하기 어렵게 합니다. 더 자세한 내용은 아래 섹션을 참조해 주세요.
https://tools.ietf.org/html/rfc7540#section-10.7



    +---------------+

    |Pad Length? (8)|

    +---------------+-----------------------------------------------+

    |                            Data (*)                                     ...

    +---------------------------------------------------------------+

    |                           Padding (*)                                 ...

    +---------------------------------------------------------------+


                       Figure 6: DATA Frame Payload



프레임의 각 필드에 대한 설명

Pad Length : 뒤의 패딩 데이터가 얼마나 붙어있는지를 나타내는 8비트 숫자값입니다. 이 필드는 PADDED 플래그가 설정되어 있을 경우에만 존재하며, 이외에는 존재하지 않습니다.


Data : 실제 유저 데이터 영역입니다. Data 영역의 실제 크기는 헤더에 포함된 payload 길이에서 패딩 관련 부분을 빼서 구할 수 있습니다. 만약 패딩이 없다면 payload 길이를 그대로 사용합니다.


Padding : 패딩은 특정한 의미가 있는 데이터를 담지 않습니다. 전송자는 항상 패딩 영역을 0으로 채워서 보내야 하고 / 수신자는 패딩 영역을 검사해야 할 의무는 없지만 0이 아닌 패딩이 감지되면 프로토콜 에러로 연결을 닫아버릴 가능성은 있습니다.




프레임이 가질 수 있는 플래그들에 대한 설명

END_STREAM (0x1) : 설정되어 있을 경우 송신자가 현재 스트림에 대해서 이번 프레임이 마지막이라는걸 알려주는 역할을 합니다. 이 플래그를 설정한 후에 "half-closed" 상태 혹은 "closed" 상태가 될 수 있습니다.


PADDED (0x8) : 설정되어 있을 경우 패딩이 포함됨을 나타냅니다. 이 경우에 Pad Length 필드와 Padding 필드가 존재합니다.




기타

* DATA 프레임은 반드시 특정한 스트림과 연관되어야 합니다. 만약 송신자가 스트림 아이디가 0인 DATA 프레임을 받았다면 반드시 프로토콜 에러와 함께 연결을 종료해야 합니다.


* DATA 프레임은 반드시 플로우컨트롤상에서 "open" 또는 "half-closed (remote)" 상태에서 보내져야 합니다. 만약 그렇지 않다면 수신측은 반드시 STREAM_CLOSED 와 함께 에러로 응답해야 합니다.


* Padding의 크기는 Pad Length필드 값에 의해서 결정됩니다. 만약 실제 패딩영역의 길이가 전체 payload 길이보다 크거나 같다면 수신자는 PROTOCOL_ERROR 와 함께 연결을 종료해야 합니다.


* Pad Length 필드가 0인 경우에도 해당 필드를 표현하기 위해 전체 payload가 1바이트 추가됩니다.


'HTTP2.0' 카테고리의 다른 글

[HTTP2.0] DATA 프레임  (0) 2016.07.06
Posted by pjc0247
TAG HTTP, HTTP2.0

WebSocket Data Frame Format



FIN : 현재 패킷이 마지막 조각임을 나타냅니다.
RSV1 ~ 3 : 특별히 지정되지 않은 경우 기본적으로 항상 0이어야 합니다. 0이 아닌 값을 지정할 경우 에러를 발생합니다. (발생시켜야 합니다.)

OPCODE : 패킷의 타입입니다.

MASK : PayloadData가 마스킹되었는지 여부를 나타냅니다. 클라이언트가 서버로 보내는 패킷은 항상 1이어야 합니다. 서버가 클라이언트로 보내는 패킷은 항상 0이어야 합니다.

PAYLOAD_LEN : PayloadData의 길이입니다. 이 값이 125이하일경우 이 필드 자체가 PayloadData의 실제 길이를 나타내며 126/127일 경우 뒤따라올 EXTENDED_PAYLOAD_LEN의 길이를 나타내는 플래그 역할을 합니다.

EXTENDED_PAYLOAD_LEN : PAYLOAD_LEN이 126 또는 127일 때에만 존재합니다. 126일 경우 2바이트 (unsigned short) 값이고 / 127일 경우 8바이트 (long long) 값입니다.

MASKING_KEY : 이 필드는 MASK가 1일때만 존재합니다. PayloadData를 언마스킹 할 때 사용할 키입니다.

PAYLOAD_DATA : 실제 데이터입니다. (UTF-8인코딩된 문자열 또는 바이너리)



주의

PAYLOAD_DATA 필드의 사이즈가 가변인건 당연하지만

EXTENDED_PAYLOAD_LEN 필드와 MASKING_KEY의 사이즈도 가변적인것에 주의해야 합니다.


* EXTENDED_PAYLOAD_LEN : 0바이트일수도 또는 2바이트 / 혹은 8바이트일 수 있습니다.

* MASKING_KEY : 0바이트일수도 / 4바이트일수도 있습니다.


예시

* 클라이언트서버에게 100바이트 문자열을 보낼 경우

PAYLOAD_LEN : 보내려는 사이즈가 125이하이므로 100을 그대로 담습니다.

EXTENDED_PAYLOAD_LEN : 이 필드는 존재하지 않습니다.

MASK : 클라이언트가 보내는 패킷은 항상 마스킹되어야 합니다. 

MASKING_KEY : MASK 값이 1이므로 이 필드는 존재합니다. 클라이언트는 이 키로 PAYLOAD_DATA를 마스킹해야 합니다.

PAYLOAD_DATA : 100바이트의 UTF-8 인코딩된 문자열을 전송합니다. 


패킷의 사이즈는

고정 2바이트(FIN/RSV/OPCODE/MASK/PAYLOAD_LEN)

MASKING_KEY 4바이트

PAYLOAD_DATA 100바이트

총 106바이트입니다.

* 서버클라이언트에게 100바이트 문자열을 보낼 경우

PAYLOAD_LEN : 보내려는 사이즈가 125이하이므로 100을 그대로 담습니다.

EXTENDED_PAYLOAD_LEN : 이 필드는 존재하지 않습니다.

MASK : 서버가 보내는 패킷은 항상 마스킹되면 안됩니다.

MASKING_KEY : MASK 값이 0이므로 이 필드는 존재하지 않아야 합니다. PAYLOAD_DATA는 마스킹되지 않은 채 보내집니다.

PAYLOAD_DATA : 100바이트의 UTF-8 인코딩된 문자열을 전송합니다. 


패킷의 사이즈는

고정 2바이트(FIN/RSV/OPCODE/MASK/PAYLOAD_LEN)

PAYLOAD_DATA 100바이트

총 102바이트입니다.


* 클라이언트서버에게 200바이트 문자열을 보낼 경우

PAYLOAD_LEN : 보내려는 사이즈가 125보다 크고 unsigned short 범위 이내이므로 126으로 설정합니다.

EXTENDED_PAYLOAD_LEN : 이 필드는 2바이트의 길이를 가지게 됩니다. 값은 200을 적습니다.

이하생략



'기타' 카테고리의 다른 글

[C++] ToString() 사용하기  (0) 2016.08.12
[VSCode] 확장 프로그램 작성하기  (0) 2016.07.11
웹소켓 프레임 구조  (0) 2016.06.30
C++의 Nested Namespace  (0) 2016.04.08
[cocos2d-x] Vibration(진동) 기능 사용하기  (0) 2016.02.22
[Lumberyard] What is Cloud Canvas?  (0) 2016.02.11
Posted by pjc0247
먼저 클라이언트에서 웹소켓 오픈 시, 서버로 아래와 같은 요청이 온다.
(일반적인 HTTP 요청의 형태에 몇몇 추가적인 헤더를 담아서 보내는 방식이다.)


여기서 살펴보야아 할 값은 Sec-WebSocket-Key인데, 이 값은 서버가 웹소켓 프로토콜을 제대로 이해하고 있는지를 구별하는 역할을 한다.

이제 서버에서는 프로토콜 업그레이드에 대한 응답을 보내주어야 한다.
상태 코드는 101번이고, 반드시 Sec-WebSocket-Accept 헤더에 알맞은 값을 채워서 보내야한다.

클라이언트로부터 받은 Sec-WebSocket-Key 값에 고정 GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 를 이어 붙인 후 SHA-1 해싱 -> base64로 인코딩한다.
(위의 GUID는 웹소켓 스펙에 정해진 고정 문자열이다.)

아래는 올바른 리스폰스의 예시 


이 요청을 보낸 후부터는 HTTP/1.1 프로토콜이 아닌 웹소켓 프로토콜로 데이터를 주고받는다.



이걸 C# 코드로 구현하면 아래와 같다.





Posted by pjc0247
TAG C#, HTTP, WebSocket