所以我决定通过给自己一些有趣的任务开始学习它。作为一个Web开发者,我想拥有自己的WebSocket服务器。 所以我写了它,但它只接受第一个请求。之后有算术运算。
下面是一些代码,让你看看我做错了什么:S我真的没有想法。在C中读取套接字时算术运算溢出了#
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using WebSocket.Utils;
namespace WebSocket
{
class SocketReader
{
public EndPoint ipAddr { get; set; }
private Socket userSocket;
private byte[] buffer;
private string SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
public SocketReader(Socket socket)
{
userSocket = socket;
ipAddr = socket.RemoteEndPoint;
Read();
}
private void Read()
{
//Read packet size
buffer = new byte[2];
userSocket.BeginReceive(buffer, 0, 2, SocketFlags.None, ReadCallbackStatic, null);
}
private void ReadCallbackStatic(IAsyncResult ar)
{
try
{
if (userSocket.EndReceive(ar) >= 1)
{
int bufferSize = BitConverter.ToInt16(buffer, 0);
buffer = new byte[bufferSize - 2];
//Read Packet
userSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReadCallback, null);
}
}
catch (Exception se)
{
Console.WriteLine("Something blew on ReadCallbackStatic");
Console.WriteLine(se.Message);
Console.WriteLine(se.StackTrace);
Disconnect();
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
//Copy the buffer so we can receive the next packet ASAP
byte[] buff = new byte[buffer.Length];
Array.Copy(buffer, buff, buffer.Length);
Read();
string handshakeStr = System.Text.Encoding.UTF8.GetString(buff);
string[] list = Regex.Split(handshakeStr, "\r\n");
//Sec-WebSocket-Key: S5o6fCVLRMJhdXTF3H9w3Q==
//Sec-WebSocket-Version: 8
string key = "";
string clientProtocol = "0";
foreach (string str in list)
{
if (String.IsNullOrEmpty(str)) { continue; }
if (str.Length > 20 && str.Substring(0, 19) == "Sec-WebSocket-Key: ")
{
key = str.Substring(19);
continue;
}
if (str.Length > 20 && str.Substring(0, 23) == "Sec-WebSocket-Version: ")
{
clientProtocol = str.Substring(23);
continue;
}
}
if (String.IsNullOrEmpty(key))
{
Disconnect();
}
SHA1 shaEnc = new SHA1CryptoServiceProvider();
byte[] byteString = ASCIIEncoding.ASCII.GetBytes(key + SOCKET_GUID);
byte[] hash = shaEnc.ComputeHash(byteString, 0, byteString.Length);
string acceptKey = Convert.ToBase64String(hash);
List<string> headers = new List<string>();
headers.Add("HTTP/1.1 101 Switching Protocols");
headers.Add("Upgrade: websocket");
headers.Add("Connection: Upgrade");
headers.Add("Sec-WebSocket-Accept: " + acceptKey);
foreach (string header in headers)
{
SendString(header + "\r\n");
}
Console.WriteLine(acceptKey);
SendString("\r\n");
}
catch (SocketException se)
{
Console.WriteLine("Something blew on ReadCallback");
Console.WriteLine(se.Message);
Disconnect();
}
}
private void SendString(string str)
{
userSocket.Send(Encoding.UTF8.GetBytes(str));
}
private void Disconnect()
{
userSocket.Disconnect(false);
Console.WriteLine("Client with ip {0} Disconnected", ipAddr);
}
}
}
它缩短了我的课的版本,但被窃听我的问题出现在“ReadCallbackStatic”在这条线:
buffer = new byte[bufferSize - 2];
我真的不知道我做错了什么:S。
的事情是,...其实我握手正常但后来当我发送来自客户端的一些信息到我的服务器则抛出该异常
我做了一些调试,看来,在某种程度上缓冲变量变为负数OO
你确定你应该减2? – harold
为了回应哈罗德的观点 - 长度标记通常不包括长度标记的大小;意思是:如果标记(长度2)报告200字节,我期望读取*附加* 2字节,因此总共202个字节。 –