웹 소켓 프레임 연구
웹 소켓 의 프로 토 콜 은 RFC 6455 에 있 습 니 다. http://tools.ietf.org/html/rfc6455#section-5.1
:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
FIN: 1 bit
Indicates that this is the final fragment in a message. The first
fragment MAY also be the final fragment.
RSV1, RSV2, RSV3: 1 bit each
MUST be 0 unless an extension is negotiated that defines meanings
for non-zero values. If a nonzero value is received and none of
the negotiated extensions defines the meaning of such a nonzero
value, the receiving endpoint MUST _Fail the WebSocket
Connection_.
Opcode: 4 bits
Defines the interpretation of the "Payload data". If an unknown
opcode is received, the receiving endpoint MUST _Fail the
WebSocket Connection_. The following values are defined.
Mask: 1 bit
Defines whether the "Payload data" is masked. If set to 1, a
masking key is present in masking-key, and this is used to unmask
the "Payload data" . All frames sent from
client to server have this bit set to 1
Payload length: 7 bits, 7+16 bits, or 7+64 bits
The length of the "Payload data", in bytes: if 0-125, that is the
payload length. If 126, the following 2 bytes interpreted as a
16-bit unsigned integer are the payload length. If 127, the
following 8 bytes interpreted as a 64-bit unsigned integer (the
most significant bit MUST be 0) are the payload length. Multibyte
length quantities are expressed in network byte order. Note that
in all cases, the minimal number of bytes MUST be used to encode
the length, for example, the length of a 124-byte-long string
can't be encoded as the sequence 126, 0, 124. The payload length
is the length of the "Extension data" + the length of the
"Application data". The length of the "Extension data" may be
zero, in which case the payload length is the length of the
"Application data".
Masking-key: 0 or 4 bytes
All frames sent from the client to the server are masked by a
32-bit value that is contained within the frame. This field is
present if the mask bit is set to 1 and is absent if the mask bit
is set to 0. See Section 5.3 for further information on client-
to-server masking.
Payload data: (x+y) bytes
The "Payload data" is defined as "Extension data" concatenated
with "Application data".
Extension data: x bytes
The "Extension data" is 0 bytes unless an extension has been
negotiated. Any extension MUST specify the length of the
"Extension data", or how that length may be calculated, and how
the extension use MUST be negotiated during the opening handshake.
If present, the "Extension data" is included in the total payload
length.
Application data: y bytes
Arbitrary "Application data", taking up the remainder of the frame
after any "Extension data". The length of the "Application data"
is equal to the payload length minus the length of the "Extension
data".
tomcat WSFrame , org\apache\catalina\websocket
private WsFrame(byte first,
UpgradeProcessor> processor) throws IOException {
//RFC6455 frame http://tools.ietf.org/html/rfc6455#section-5.1
int b = first & 0xFF; // 32
fin = (b & 0x80) > 0; // 8 10000000>0
rsv = (b & 0x70) >>> 4; // 5、6、7 01110000 00000111
opCode = (byte) (b & 0x0F); // opCode 00001111
b = blockingRead(processor); //
// Client data must be masked
if ((b & 0x80) == 0) { // 9 mask, 1
throw new IOException(sm.getString("frame.notMasked"));
}
payloadLength = b & 0x7F; // 7 Payload legth, 125 payloadLength
if (payloadLength == 126) { // 126 2 , payloadLength
byte[] extended = new byte[2];
blockingRead(processor, extended);
payloadLength = Conversions.byteArrayToLong(extended); // 2 LONG
} else if (payloadLength == 127) { //127 8 , 8 payloadLength
byte[] extended = new byte[8];
blockingRead(processor, extended);
payloadLength = Conversions.byteArrayToLong(extended);//8 LONG
}
if (isControl()) {
if (payloadLength > 125) {
throw new IOException();
}
if (!fin) {
throw new IOException();
}
}
blockingRead(processor, mask);// MASK-KEY:0or4 ,mask 1 4
if (isControl()) {
// Note: Payload limited to <= 125 bytes by test above
payload = ByteBuffer.allocate((int) payloadLength);
blockingRead(processor, payload); // payloadLength payload
if (opCode == Constants.OPCODE_CLOSE && payloadLength > 2) {
// Check close payload - if present - is valid UTF-8
CharBuffer cb = CharBuffer.allocate((int) payloadLength);
Utf8Decoder decoder = new Utf8Decoder(); // UTF-8
payload.position(2);
CoderResult cr = decoder.decode(payload, cb, true);// 3
payload.position(0);
if (cr.isError()) {
throw new IOException(sm.getString("frame.invalidUtf8"));
}
}
} else {
payload = null;
}
}
private int blockingRead(UpgradeProcessor> processor)
throws IOException {
int result = processor.read();
if (result == -1) {
throw new IOException(sm.getString("frame.eos"));
}
return result;
}
/*
* Blocks until the byte array has been filled.
*/
private void blockingRead(UpgradeProcessor> processor, byte[] bytes) // bytes.length
throws IOException {
int read = 0;
int last = 0;
while (read < bytes.length) {
last = processor.read(true, bytes, read, bytes.length - read);
if (last == -1) {
throw new IOException(sm.getString("frame.eos"));
}
read += last;
}
}
/*
* Intended to read whole payload and blocks until it has. Therefore able to
* unmask the payload data.
*/
private void blockingRead(UpgradeProcessor> processor, ByteBuffer bb)
throws IOException {
int last = 0;
while (bb.hasRemaining()) {
last = processor.read();
if (last == -1) {
throw new IOException(sm.getString("frame.eos"));
}
bb.put((byte) (last ^ mask[bb.position() % 4]));
}
bb.flip();
}
다음으로 전송:https://www.cnblogs.com/imayi/archive/2012/05/05/2485343.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.