Websocket Server crash beim BeginAccept

  • C#
  • .NET (FX) 4.0

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Goldwing Studios.

    Websocket Server crash beim BeginAccept

    Hallo,
    ich habe hier ein Websocket-Script welches ich mir aus ein paar Foren ein bisschen zusammen gewurschtelt habe und habe jetzt allerdings ein Problem, das Programm beendet sich einfach Sang- und Klanglos in der Zeile 99.
    Sonst klappt alles perfekt, Daten werden vom Client und zurück gesendet.

    Weiß zufällig jemand warum das Programm abbricht?

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Net;
    5. using System.Net.Sockets;
    6. using System.Security.Cryptography;
    7. using System.Text;
    8. using System.Threading;
    9. using System.Threading.Tasks;
    10. namespace WebSockets_Test
    11. {
    12. class Program
    13. {
    14. static Socket serverSocket = new Socket(AddressFamily.InterNetwork,
    15. SocketType.Stream, ProtocolType.IP);
    16. static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    17. static void Main(string[] args)
    18. {
    19. serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
    20. serverSocket.Listen(128);
    21. serverSocket.BeginAccept(null, 0, OnAccept, null);
    22. Console.Read();
    23. }
    24. private static void OnAccept(IAsyncResult result)
    25. {
    26. byte[] buffer = new byte[1024];
    27. try
    28. {
    29. Socket client = null;
    30. string headerResponse = "";
    31. if (serverSocket != null && serverSocket.IsBound)
    32. {
    33. client = serverSocket.EndAccept(result);
    34. var i = client.Receive(buffer);
    35. headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i);
    36. // write received data to the console
    37. Console.WriteLine(headerResponse);
    38. }
    39. if (client != null)
    40. {
    41. /* Handshaking and managing ClientSocket */
    42. var key = headerResponse.Replace("ey:", "`")
    43. .Split('`')[1] // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
    44. .Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ==
    45. .Trim();
    46. // key should now equal dGhlIHNhbXBsZSBub25jZQ==
    47. var test1 = AcceptKey(ref key);
    48. var newLine = "\r\n";
    49. var response = "HTTP/1.1 101 Switching Protocols" + newLine
    50. + "Upgrade: websocket" + newLine
    51. + "Connection: Upgrade" + newLine
    52. + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
    53. //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
    54. //+ "Sec-WebSocket-Version: 13" + newLine
    55. ;
    56. // which one should I use? none of them fires the onopen method
    57. client.Send(System.Text.Encoding.UTF8.GetBytes(response));
    58. var i = client.Receive(buffer); // wait for client to send a message
    59. // once the message is received decode it in different formats
    60. Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));
    61. try
    62. {
    63. if (serverSocket != null && serverSocket.IsBound)
    64. {
    65. var Respone = EncodeMessageToSend("Test");
    66. client.Send(Respone);
    67. }
    68. }
    69. catch (Exception ex)
    70. {
    71. Console.Write(ex);
    72. }
    73. Thread.Sleep(5000);//wait for message to be send
    74. }
    75. }
    76. catch (SocketException exception)
    77. {
    78. throw exception;
    79. }
    80. finally
    81. {
    82. if (serverSocket != null && serverSocket.IsBound)
    83. {
    84. try
    85. {
    86. serverSocket.BeginAccept(null, 0, OnAccept, null);
    87. }
    88. catch (SocketException exception)
    89. {
    90. throw exception;
    91. }
    92. }
    93. }
    94. }
    95. private static Byte[] EncodeMessageToSend(String message)
    96. {
    97. Byte[] response;
    98. Byte[] bytesRaw = Encoding.UTF8.GetBytes(message);
    99. Byte[] frame = new Byte[10];
    100. Int32 indexStartRawData = -1;
    101. Int32 length = bytesRaw.Length;
    102. frame[0] = (Byte)129;
    103. if (length <= 125)
    104. {
    105. frame[1] = (Byte)length;
    106. indexStartRawData = 2;
    107. }
    108. else if (length >= 126 && length <= 65535)
    109. {
    110. frame[1] = (Byte)126;
    111. frame[2] = (Byte)((length >> 8) & 255);
    112. frame[3] = (Byte)(length & 255);
    113. indexStartRawData = 4;
    114. }
    115. else
    116. {
    117. frame[1] = (Byte)127;
    118. frame[2] = (Byte)((length >> 56) & 255);
    119. frame[3] = (Byte)((length >> 48) & 255);
    120. frame[4] = (Byte)((length >> 40) & 255);
    121. frame[5] = (Byte)((length >> 32) & 255);
    122. frame[6] = (Byte)((length >> 24) & 255);
    123. frame[7] = (Byte)((length >> 16) & 255);
    124. frame[8] = (Byte)((length >> 8) & 255);
    125. frame[9] = (Byte)(length & 255);
    126. indexStartRawData = 10;
    127. }
    128. response = new Byte[indexStartRawData + length];
    129. Int32 i, reponseIdx = 0;
    130. //Add the frame bytes to the reponse
    131. for (i = 0; i < indexStartRawData; i++)
    132. {
    133. response[reponseIdx] = frame[i];
    134. reponseIdx++;
    135. }
    136. //Add the data bytes to the response
    137. for (i = 0; i < length; i++)
    138. {
    139. response[reponseIdx] = bytesRaw[i];
    140. reponseIdx++;
    141. }
    142. return response;
    143. }
    144. private static string AcceptKey(ref string key)
    145. {
    146. string longKey = key + guid;
    147. byte[] hashBytes = ComputeHash(longKey);
    148. return Convert.ToBase64String(hashBytes);
    149. }
    150. static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
    151. private static byte[] ComputeHash(string str)
    152. {
    153. return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str));
    154. }
    155. }
    156. }​
    Es lag daran, dass ich immer so doof war und während des Window-Focus irgendwelche Tasten zu drücken um halt das Console.Read() zu feuern und deshalb ist er immer so still und heimlich abgerauscht.

    Hab mir jetzt aber angewöhnt, das zu unterlassen bzw. habe mir jetzt eh einen Message-Loop eingefuddelt und das läuft nun besser:

    C#-Quellcode

    1. ​while ((i = client.Receive(buffer)) > 6)
    2. {
    3. var cmd = DecodeMessage(buffer).Substring(0, i);
    4. var Respone = EncodeMessageToSend(exec_command(cmd));
    5. if (serverSocket != null && serverSocket.IsBound)
    6. {
    7. client.Send(Respone);
    8. }
    9. }


    Ich kann damit nun Befehle vom Client empfangen und Antworten zurücksenden, das klappt auch herz-allerliebst!