我用C#制作了一个Websocket服务器,并与JS一起制作了一个HTML UI。
我可以让服务器进行通信并正确握手,但是发送的信息绝对是胡言乱语,看起来像这样:
???=u??X?G?
我尝试过对其进行编码,但结果并没有太大的不同。
我的JS看起来像这样:
// the user clicked the big red button
$('#bigredbutton_send').click(function () {
ws_send($('#console_input').val());
});
$('#console_input').keyup(function (e) {
if(e.keyCode == 13) // enter is pressed
ws_send($('#console_input').val());
});
.CSS:
<input type="image" src="button.png" name="bigredbutton_send" id="bigredbutton_send" value="VALUE" />
<input type="text" name="console_input" id="console_input" value="Hello123" />
接收信息的 C# 模块如下所示:
private void Read(IAsyncResult ar)
{
int sizeOfReceivedData = ConnectionSocket.EndReceive(ar);
if (sizeOfReceivedData > 0)
{
int start = 0, end = dataBuffer.Length - 1;
// if we are not already reading something, look for the start byte as specified in the protocol
if (!readingData)
{
for (start = 0; start < dataBuffer.Length - 1; start++)
{
if (dataBuffer[start] == (byte)WrapperBytes.Start)
{
readingData = true; // we found the begining and can now start reading
start++; // we dont need the start byte. Incrementing the start counter will walk us past it
break;
}
}
} // no else here, the value of readingData might have changed
// if a begining was found in the buffer, or if we are continuing from another buffer
if (readingData)
{
bool endIsInThisBuffer = false;
// look for the end byte in the received data
for (end = start; end < sizeOfReceivedData; end++)
{
byte currentByte = dataBuffer[end];
if (dataBuffer[end] == (byte)WrapperBytes.End)
{
endIsInThisBuffer = true; // we found the ending byte
break;
}
}
// the end is in this buffer, which means that we are done reading
if (endIsInThisBuffer == true)
{
// we are no longer reading data
readingData = false;
// put the data into the string builder
dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, end - start));
// trigger the event
int size = Encoding.UTF8.GetBytes(dataString.ToString().ToCharArray()).Length;
recievedData = dataString.ToString();
OnDataReceived(new DataReceivedEventArgs(size, dataString.ToString()));
dataString = null;
dataString = new StringBuilder();
}
else // if the end is not in this buffer then put everyting from start to the end of the buffer into the datastring and keep on reading
{
dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, end - start));
}
}
// continue listening for more data
Listen();
}
else // the socket is closed
{
if (Disconnected != null)
Disconnected(this, EventArgs.Empty);
}
// Testing to see if readable
ReadRecievedData(Convert.ToString(dataString));
}
它们都返回一些东西,但是,它们总是返回这个原始的、乱码状的数据,看起来像这样:
???=u??X?G?
我知道它缺乏编码,并且我已经尝试对其进行了几次编码 - 但这些信息看起来更奇怪,实际上永远不会返回我想要的任何内容。任何帮助将不胜感激。
更新
在调用新连接时调用 dataBuffer。
public WebSocketConnection(Socket socket, int bufferSize)
{
ConnectionSocket = socket;
dataBuffer = new byte[bufferSize];
dataString = new StringBuilder();
GUID = System.Guid.NewGuid();
Listen();
}
Listen() 创建这个:
private void Listen()
{
ConnectionSocket.BeginReceive(dataBuffer, 0, dataBuffer.Length, 0, Read, null);
}
解决!
我昨天又看了一遍,我解决了问题。我没有正确解析位 - 所以我创建了这个:
byte b = dataBuffer[1];
int dataLength = 0;
int totalLength = 0;
int keyIndex = 0;
int length = dataBuffer.Length;
if (b - 128 <= 125)
{
dataLength = b - 128;
keyIndex = 2;
totalLength = dataLength + 6;
}
if (b - 128 == 126)
{
dataLength = BitConverter.ToInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0);
keyIndex = 4;
totalLength = dataLength + 8;
}
if (b - 128 == 127)
{
dataLength = (int)BitConverter.ToInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4],
dataBuffer[3], dataBuffer[2] }, 0);
keyIndex = 10;
totalLength = dataLength + 14;
}
if (totalLength > length)
throw new Exception("The buffer length is small than the data length");
byte[] key = new byte[] { dataBuffer[keyIndex], dataBuffer[keyIndex + 1], dataBuffer[keyIndex + 2], dataBuffer[keyIndex + 3] };
int dataIndex = keyIndex + 4;
int count = 0;
for (int i = dataIndex; i < totalLength; i++)
{
dataBuffer[i] = (byte)(dataBuffer[i] ^ key[count % 4]);
count++;
}
ReadRecievedData(Encoding.ASCII.GetString(dataBuffer, dataIndex, dataLength));
它基于此处的解决方案构建如何在 WebSockets hybi 08+ 中(解)建数据帧?
WebSocket 数据是成帧的,因此您必须逐帧读取并从中提取数据。
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
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
用 C# 编写 WebSocket 服务器
编写 WebSocket 服务器
请尝试这个
private void Read(IAsyncResult ar)
{
int sizeOfReceivedData = ConnectionSocket.EndReceive(ar);
if (sizeOfReceivedData > 0)
{
int start = 0, end = sizeOfReceivedData - 1;
var bufferList = dataBuffer.ToList();
bool endIsInThisBuffer = dataBuffer.Contains(255); // 255 = end
if (endIsInThisBuffer)
{
end = bufferList.IndexOf(255);
end--; // we dont want to include this byte
}
bool startIsInThisBuffer = dataBuffer.Contains(0); // 0 = start
if (startIsInThisBuffer)
{
var zeroPos = bufferList.IndexOf(0);
if (zeroPos < end) // we might be looking at one of the bytes in the end of the array that hasn't been set
{
start = zeroPos;
start++; // we dont want to include this byte
}
}
dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, (end - start) + 1));
if (endIsInThisBuffer)
{
var data = dataString.ToString();
OnDataReceived(new DataReceivedEventArgs(data.Length, data));
// Testing to see if readable
ReadRecievedData(data);
dataString = new StringBuilder();
}
Listen();
}
else // the socket is closed
{
if (Disconnected != null)
Disconnected(this, EventArgs.Empty);
}
}
解决了!
我昨天又看了一遍,我解决了问题。我没有正确解析位 - 所以我创建了这个:
byte b = dataBuffer[1];
int dataLength = 0;
int totalLength = 0;
int keyIndex = 0;
int length = dataBuffer.Length;
if (b - 128 <= 125)
{
dataLength = b - 128;
keyIndex = 2;
totalLength = dataLength + 6;
}
if (b - 128 == 126)
{
dataLength = BitConverter.ToInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0);
keyIndex = 4;
totalLength = dataLength + 8;
}
if (b - 128 == 127)
{
dataLength = (int)BitConverter.ToInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4],
dataBuffer[3], dataBuffer[2] }, 0);
keyIndex = 10;
totalLength = dataLength + 14;
}
if (totalLength > length)
throw new Exception("The buffer length is small than the data length");
byte[] key = new byte[] { dataBuffer[keyIndex], dataBuffer[keyIndex + 1], dataBuffer[keyIndex + 2], dataBuffer[keyIndex + 3] };
int dataIndex = keyIndex + 4;
int count = 0;
for (int i = dataIndex; i < totalLength; i++)
{
dataBuffer[i] = (byte)(dataBuffer[i] ^ key[count % 4]);
count++;
}
ReadRecievedData(Encoding.ASCII.GetString(dataBuffer, dataIndex, dataLength));
它基于此处的解决方案构建如何在 WebSockets hybi 08+ 中(解)建数据帧?