我有一个使用webrtc捕获框架的网站。该框架需要通过Internet发送到将处理该框架的Windows窗体应用程序中。
var data = Canvas.toDataURL('image/png');
$.ajax({
url: 'http://localhost',
type: 'POST',
contentType: 'application/octet-stream',
data: data,
processData: false
});
因此,我使TcpListerner侦听端口80,并且当连接打开时,此代码将运行:
byte[] bytes = new byte[Server.PackageSize];
int bytesRec = -1;
do
{
// Get the package
if (Server.InputUseSSL)
{
bytesRec = SslStream.Read(bytes, 0, bytes.Length);
}
else
{
bytesRec = NetworkStream.Read(bytes, 0, bytes.Length);
}
// Clean the array
byte[] cleanbytes = new byte[bytesRec];
Buffer.BlockCopy(bytes, 0, cleanbytes, 0, bytesRec);
var text = System.Text.Encoding.Default.GetString(cleanbytes);
// OPTIONS / HTTP/1.1
// Host: localhost
// Connection: keep-alive
// Access-Control-Request-Method: POST
// Origin: https://localhost:44323
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
// Access-Control-Request-Headers: content-type
// Accept: */*
// Accept-Encoding: gzip, deflate, br
// Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
} while (bytesRec != 0 && Socket.Connected && !IsAlreadyStopped && !StopSwitch);
我对OPTIONS http标头有什么反应?
为什么我没有得到文件?
为什么这么难? (我在过去的6个小时里一直在尝试这个,这让我很不高兴)
答案 0 :(得分:1)
应该使用了websocket:
JavaScript
ChangeConnection: function () {
if ($("#ServerAddress").val() !== '') {
try {
Camera.Connection = new WebSocket('ws://' + $("#ServerAddress").val() + ':80');
Camera.Connection.onmessage = Camera.DataReceived;
Camera.Connection.onopen = function (e) {
Camera.ConnectionOpen = true;
Camera.Connection.send("Start");
};
Camera.Connection.onclose = function (e) {
Camera.ConnectionOpen = false;
};
}
catch (ex) {
Log(ex);
}
}
},
DataReceived: function (e) {
var data = e.data;
Log("Data received:\n" + data);
},
CaputerFrame: function () {
var context = Camera.Canvas.getContext('2d');
context.drawImage(Camera.Video, 0, 0, Camera.Width, Camera.Height);
var data = Camera.Canvas.toDataURL('image/png');
Camera.Connection.send("Frame: " + data);
Log("Frame send");
},
C#
/// <summary>
/// The thread function that handles data received from client connected to this server
/// </summary>
void ReceivePoller()
{
// Connect the socket to the remote endpoint. Catch any errors.
try
{
var bytes = new byte[Server.PackageSize];
var package = new List<byte>();
var bytesRec = -1;
var handshakesend = false;
List<byte> blob = new List<byte>();
do
{
// Get the package
if (Server.InputUseSSL)
bytesRec = SslStream.Read(bytes, 0, bytes.Length);
else
bytesRec = NetworkStream.Read(bytes, 0, bytes.Length);
// Clean the array
byte[] cleanbytes = new byte[bytesRec];
Buffer.BlockCopy(bytes, 0, cleanbytes, 0, bytesRec);
// Check if handshaken
if (!handshakesend)
{
var data = System.Text.Encoding.Default.GetString(cleanbytes);
if (Server.Debug)
Context.Logging.Message(IpAddress + "<-- " + data.Length + " B: " + data);
if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
{
const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker
var response = "HTTP/1.1 101 Switching Protocols" + eol
+ "Connection: Upgrade" + eol
+ "Upgrade: websocket" + eol
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
System.Security.Cryptography.SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + eol
+ eol;
Byte[] responseBytes = Encoding.UTF8.GetBytes(response);
NetworkStream.Write(responseBytes, 0, responseBytes.Length);
if (Server.Debug)
Context.Logging.Message(IpAddress + "--> " + response.Length + " B: " + response);
handshakesend = true;
}
else
{
// Shut it down man!
Stop();
}
}
else
{
blob.AddRange(cleanbytes);
if (!NetworkStream.DataAvailable)
{
// Decode the received data
var data = DecodedData(blob.ToArray(), blob.Count);
if (Server.Debug)
Context.Logging.Message(IpAddress + "<-- " + data.Length + " B: " + data);
// Process message
Server.ProcessMessage(this, data);
// Reset the blob
blob.Clear();
}
}
} while (bytesRec != 0 && Socket.Connected && !IsAlreadyStopped && !StopSwitch);
}
catch (System.IO.IOException ex)
{
}
catch (SocketException ex)
{
}
catch (Exception ex)
{
// When the connection is lost the waiting thread will be ended with a exception.
// We use this to notify the other connection (LAN) that the connection has ended.
// So there is no need to see this in our error logging.
if (Server.Debug) Context.Logging.Message(IpAddress + " Client.DataReceive ERROR" + Environment.NewLine + ex.ToString());
}
// Stop the client just in case
Stop();
}
/// <summary>
/// Will decode the received byte array from the websocket
/// </summary>
/// <param name="buffer"></param>
/// <param name="length"></param>
/// <returns></returns>
string DecodedData(byte[] buffer, int length)
{
byte b = buffer[1];
int dataLength = 0;
int totalLength = 0;
int keyIndex = 0;
if (b - 128 <= 125)
{
dataLength = b - 128;
keyIndex = 2;
totalLength = dataLength + 6;
}
if (b - 128 == 126)
{
dataLength = BitConverter.ToInt16(new byte[] { buffer[3], buffer[2] }, 0);
keyIndex = 4;
totalLength = dataLength + 8;
}
if (b - 128 == 127)
{
dataLength = (int)BitConverter.ToInt64(new byte[] { buffer[9], buffer[8], buffer[7], buffer[6], buffer[5], buffer[4], buffer[3], buffer[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[] { buffer[keyIndex], buffer[keyIndex + 1], buffer[keyIndex + 2], buffer[keyIndex + 3] };
int dataIndex = keyIndex + 4;
int count = 0;
for (int i = dataIndex; i < totalLength; i++)
{
buffer[i] = (byte)(buffer[i] ^ key[count % 4]);
count++;
}
return Encoding.ASCII.GetString(buffer, dataIndex, dataLength);
}
/// <summary>
/// Function used by the LAN receive data thread
/// </summary>
/// <param name="data">Data to send</param>
public void SendData(string data)
{
try
{
var bytes = Encoding.UTF8.GetBytes(data);
SendData(bytes, bytes.Length);
}
catch (Exception ex)
{
if (Server.Debug) Context.Logging.Warning(ex);
}
}
/// <summary>
/// Function used by the LAN receive data thread
/// </summary>
/// <param name="bytes">Data to send</param>
/// <param name="length">Length of the data to send</param>
public void SendData(byte[] bytes, int length)
{
try
{
if (!IsAlreadyStopped && !StopSwitch)
{
if (Server.InputUseSSL)
SslStream.Write(bytes);
else
NetworkStream.Write(bytes, 0, length);
if (Server.Debug) Context.Logging.Message(IpAddress + "--> " + bytes.Length + " B: " + System.Text.Encoding.Default.GetString(bytes));
}
}
catch (Exception ex)
{
if (Server.Debug) Context.Logging.Warning(ex);
}
}