2013-06-05 2 views
1

WS 및 C# console 응용 프로그램을 사용하여 Websocket을 처음 사용하고 작업 샘플을 찾고 있습니다. this one이 발생했지만 이미 문제가 있습니다. 서버가 클라이언트에게 메시지를 보낼 때 연결이 닫힌 것 같습니다. 나는 확실하지 않다. 그러나 나는 악수가 OK 다라고 생각한다. 여기 코드는 다음과 같습니다웹 소켓 - 서버 메시지의 연결 해제

서버 :

using System; 
using System.Net.Sockets; 
using System.Net; 
using System.Security.Cryptography; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
     static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 

     static void Main(string[] args) 
     { 
      serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); 
      serverSocket.Listen(128); 
      serverSocket.BeginAccept(null, 0, OnAccept, null); 
      Console.Read(); 
     } 

     private static void OnAccept(IAsyncResult result) 
     { 
      byte[] buffer = new byte[1024]; 
      try 
      { 
       Socket client = null; 
       string headerResponse = ""; 
       if (serverSocket != null && serverSocket.IsBound) 
       { 
        client = serverSocket.EndAccept(result); 
        var i = client.Receive(buffer); 
        headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i); 
        // write received data to the console 
        Console.WriteLine(headerResponse); 
        Console.WriteLine("====================="); 
       } 
       if (client != null) 
       { 
        /* Handshaking and managing ClientSocket */ 

        var key = headerResponse.Replace("ey:", "`") 
           .Split('`')[1]      // dGhlIHNhbXBsZSBub25jZQ== \r\n ....... 
           .Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ== 
           .Trim(); 

        // key should now equal dGhlIHNhbXBsZSBub25jZQ== 
        var test1 = AcceptKey(ref key); 

        var newLine = "\r\n"; 

        var response = "HTTP/1.1 101 Switching Protocols" + newLine 
         + "Upgrade: websocket" + newLine 
         + "Connection: Upgrade" + newLine 
         + "Sec-WebSocket-Accept: " + test1 + newLine + newLine 
         //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine 
         //+ "Sec-WebSocket-Version: 13" + newLine 
         ; 

        // which one should I use? none of them fires the onopen method 
        client.Send(System.Text.Encoding.UTF8.GetBytes(response)); 

        var i = client.Receive(buffer); // wait for client to send a message 

        // once the message is received decode it in different formats 
        Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i)); 
        Console.WriteLine("====================="); 

        Console.WriteLine("\n\nPress enter to send data to client"); 
        Console.Read(); 

        var subA = SubArray<byte>(buffer, 0, i); 
        client.Send(subA); 

        Console.Read();      
        Thread.Sleep(10000);//wait for message to be send 


       } 
      } 
      catch (SocketException exception) 
      { 
       throw exception; 
      } 
      finally 
      { 
       if (serverSocket != null && serverSocket.IsBound) 
       { 
        serverSocket.BeginAccept(null, 0, OnAccept, null); 
       } 
      } 
     } 

     public static T[] SubArray<T>(T[] data, int index, int length) 
     { 
      T[] result = new T[length]; 
      Array.Copy(data, index, result, 0, length); 
      return result; 
     } 

     private static string AcceptKey(ref string key) 
     { 
      string longKey = key + guid; 
      byte[] hashBytes = ComputeHash(longKey); 
      return Convert.ToBase64String(hashBytes); 
     } 

     static SHA1 sha1 = SHA1CryptoServiceProvider.Create(); 
     private static byte[] ComputeHash(string str) 
     { 
      return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str)); 
     } 
    } 
} 

Clent : 여기

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <script type="text/javascript"> 
     function connect() { 
      var ws = new WebSocket("ws://localhost:8080/service"); 
      ws.onopen = function() { 
       alert("About to send data"); 
       ws.send("Hello World"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!! 
       alert("Message sent!"); 
      }; 

      ws.onmessage = function (evt) { 
       alert("About to receive data"); 
       var received_msg = evt.data; 
       alert("Message received = "+received_msg); 
      }; 
      ws.onclose = function() { 
       // websocket is closed. 
       alert("Connection is closed..."); 
      }; 
     }; 


    </script> 
</head> 
<body style="font-size:xx-large" > 
    <div> 
    <a href="#" onclick="connect()">Click here to start</a></div> 
</body> 
</html> 

는 클라이언트의 연결 요청 및 메시지 : 어떤 도움을 이해할 수있을 것이다 enter image description here

.

답변

2

받은 버퍼를 "에코"할 수 없습니다. RFC는 클라이언트에서 서버로 보내는 프레임을 가려야한다고 말합니다. 서버에서 클라이언트로 전송되는 메일은 전송해서는 안되지만 적어도 Chrome에서는 그렇지 않아야한다고 말하지 않습니다. 따라서 데이터를 에코하려면 프레임을 디코딩 (마스크 해제)하고 새 프레임을 생성해야합니다. 페이로드는 마스크 키와 함께 바이트 단위로 XOR되어야합니다.

또는 단순히이 같은 데이터를 전송 :

byte[] send = new byte[3 + 2]; 
send[0] = 0x81; // last frame, text 
send[1] = 3; // not masked, length 3 
send[2] = 0x41; 
send[3] = 0x42; 
send[4] = 0x43; 
nwStream.Write(send, 0, send.Length); // nwStream = client.GetStream(), client is a TcpClient 
3

JeffRSon가 올바른지. 그러나 RFC 6455의 5.1 절에 언급되어 있습니다.

... 서버는 클라이언트에 보내는 프레임을 마스크해서는 안됩니다. 클라이언트는 마스크 된 프레임을 발견하면 연결을 종료해야합니다. ...

+0

문제를 해결할 수 있었습니까? –