# websocket Frame研究

websocket 的协议在RFC6455中  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
+-+-+-+-+-------+-+-------------+-------------------------------+
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ - - - - - - - - - - - - - - - +-------------------------------+
+-------------------------------+-------------------------------+
+-------------------------------- - - - - - - - - - - - - - - - +
:                     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
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-

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,
//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

// Client data must be masked
if ((b & 0x80) == 0) {          //第9为为mask,必须为1
}

byte[] extended = new byte[2];
byte[] extended = new byte[8];
}

if (isControl()) {
throw new IOException();
}
if (!fin) {
throw new IOException();
}
}

if (isControl()) {
// Note: Payload limited to <= 125 bytes by test above

if (opCode == Constants.OPCODE_CLOSE && payloadLength > 2) {
// Check close payload - if present - is valid UTF-8
Utf8Decoder decoder = new Utf8Decoder();     //将字节解码成UTF-8格式
CoderResult cr = decoder.decode(payload, cb, true);//从第3个开始
if (cr.isError()) {
throw new IOException(sm.getString("frame.invalidUtf8"));
}
}
} else {
}
}
  private int blockingRead(UpgradeProcessor<?> processor)
throws IOException {
if (result == -1) {
throw new IOException(sm.getString("frame.eos"));
}
return result;
}

/*
* Blocks until the byte array has been filled.
*/
throws IOException {
int last = 0;
if (last == -1) {
throw new IOException(sm.getString("frame.eos"));
}
}
}

/*
* Intended to read whole payload and blocks until it has. Therefore able to
*/
}