2017-02-02 8 views
0

C#でWebソケットサーバーを開発していると、Web Socketが正しくアップグレードされていますが、フレーム受信時にフレームが正しく表示されないようですが、C#WebSocketサーバーフレームデコードが動作していないとメッセージが分からないオペコード

public string ByteArrayToString(byte[] ba) 
{ 
    StringBuilder hex = new StringBuilder(ba.Length * 2); 
    foreach (byte b in ba) 
     hex.AppendFormat("{0:x2}", b); 
    return hex.ToString(); 
} 

private string decryptFrame(Socket sock) 
{ 
    // busy wait untill something is sent 
    while (sock.Available == 0) { } 

    var header = new byte[6]; 
    sock.Receive(header); 
    var length = header[1] & 127; 

    Console.WriteLine("Recived header >> " + this.ByteArrayToString(header)); 

    var body = new byte[length]; 
    sock.Receive(body); 
    Console.WriteLine("Recived body >> " + this.ByteArrayToString(body)); 
    for (var i = 0; i < length; i++) 
    { 
     body[i] ^= header[2 + (i & 3)]; 
    } 
    Console.WriteLine("decoded body >> " + this.ByteArrayToString(body)); 
    string resp = Encoding.UTF8.GetString(body, 0, length); 
    Console.WriteLine("Parsed body >> " + resp); 
    return resp; 
} 

問題はクロームフレームがインであるということである:フレームから

bool started = false; 
// to write something back. 
while (bClientConnected) 
{ 
    try 
    { 
     msg = this.decryptFrame(client.Client); 
     Console.WriteLine("Client Frame Decrypt: " + msg); 
     //sWriter.WriteLine("pong!"); 
     //sWriter.Flush(); 
    } 
    catch (Exception) 
    { 
     Console.WriteLine("Connection from " + ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString() + " was terminated unkown reason."); 
     bClientConnected = false; 
     client.Close(); 
     continue; 
    } 
    started = true; 
} 

コード解析用とフレームのデバッグを読んで処理するための

コードtantlyフレーム内(Opcode -1)表示を示すと

Recived header >> 88909495d0d4 
Recived body >> 977f85bafffbbfa3fab5bfa4f7fab4b1 
decoded body >> 03ea556e6b6e6f776e206f70636f6465 
Parsed body >> ?Unknown opcode 
Client Frame Decrypt: ?Unknown opcode 

答えて

0

これは、Chrome & Firefoxに現在実装されている実装に問題があるように見えるため、\ r \ nがの行を終了していないことが原因ですヘッダので、スペースが問題はそれはそれはそう単純で聞こえる何かヘッダに\r\nに関してとブラウザでの実装に問題がある

"HTTP/1.1 101 Switching Protocols\r\n" 
+ "Connection: Upgrade\r\n" 
+ "Upgrade: websocket\r\n" 
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
    SHA1.Create().ComputeHash(
     Encoding.UTF8.GetBytes(
      new Regex("Sec-WebSocket-Key: (.*)").Match(headerBlock).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 
      ) 
     ) 
    ) + " \r\n\r\n"; 
2

この記事は、良いスタートであると私のサーバーに送信されたフレームのみをデバッグしている:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers

は、具体的には、私はあなたがうまくthe frame length処理していないと思います。

  1. 読み取りビット9-15(含む)と符号なし 整数としてそれを解釈します。それが125以下であれば、それは長さです。あなたは終わった。 126の場合は手順2に進みます。127の場合は手順3に進みます。
  2. 次の16ビットを読み取り、それらを符号なし整数として解釈します。あなたは終わった。

  3. 次の64ビットを読み取り、それらを符号なし整数 (最上位ビットは0でなければならない)として解釈する。あなたは終わった。

私はここにVSを持っていないが、ここであなたは癖の例を行く:

var buffer = new byte[8192]; 

// put a frame in the buffer 
// I am assuming that the frame is complete, starting at byte 0. 
// Usually you will have to deal with incomplete frames 
FillBuffer(buffer); 

// length is in the second byte 
int length = buffer[1]; 

// in the second byte, the first bit enables or disables MASK 
// this bit would add a value of +128 (2^7) if enabled 
length = (value >= 128 ? value - 128:value); 
if(length == 126) // medium size frame 
    length = BitConverter.ToUint16(frame, 2); 
else if(length == 127) // big ass frame 
    length = BitConverter.ToUint64(frame, 2); 
else if(length > 127) 
    throw new InvalidOperationException($"Invalid frame length {length}"); 

私はC#でのWebSocketコンポーネントを開発あなたは疑問を持っている場合、あなたは面白いコードを見つけることがあります。 https://github.com/vtortola/WebSocketListener

+0

、問題は、私はビットで動作することはできませんですので、必要とされますC#のレベルではバイトレベルで、9と15の両方はバイト位置にありません。 8ビット= 1バイト、[0,1,2,3,4,5,6,7] [8,9,10,11,12,13,14,15]だから私は間違った8番目のビットが私のバイトポジション2で –

+0

私は小さな例で答えを更新しました – vtortola

+0

更新していただきありがとうございます。それでは、バッファを4(32ビット)に変更できますか?ヘッダーのみを読み込むには?理由のメソッドとして私はSocket.Receiveを使用している場合は、フレームのための定数バイト長さがあればいいだろう。 –

関連する問題