我將給出一個小小的介紹:我在c#上使用一個小屏幕共享項目,並使用Tcp Protocol
來發送數據。基本上我叫GDI的BitBlt
方法,它的工作非常好。在我第一次發送整個緩衝區,然後我迭代並只發送更改的像素。 在我發送緩衝器中的每個字節表示(在RGBA順序)的組件 - 這是一個簡單的例子小的陣列:C#減少網絡帶寬使用
byte[] pixelarray = { 45, 201, 173,1 };
//R=45,G=201,B=173,Alpha=1(always 1 on screen).
允許繼續前進。 我的屏幕是1920x1080(在我的情況)所以實際上1920x1080x4(每個像素是4字節)=高達8,294,400像素。 使用Gzipstream
這樣的壓縮將大小減小到〜250kb。這是我第一次發送的內容。之後,我只是比較每個BitBlt
捕獲的字節數組,並只發送已更改的像素。它看起來像這樣:
public void StartAsync(ScreenFrame frame)
{
using (var memoryStream = new MemoryStream())
{
for (var i = 0; i < frame.NewPixels.Length; i += 4)
{
memoryStream.WriteByte(frame.NewPixels[i]);
memoryStream.WriteByte(frame.NewPixels[i + 1]);
memoryStream.WriteByte(frame.NewPixels[i + 2]);
}
byte[] data = compress(memoryStream.ToArray());//compress gzip.
SendVarData(data);//this is a simple function to send it on a socket.
}
}
public void DeltaAsync(ScreenFrame frame)
{
using (var memoryStream = new MemoryStream())
{
for (var i = 0; i < frame.NewPixels.Length; i += 4)//loop through buffers and write only differnt bytes.
{
if (frame.NewPixels[i] == frame.PreviousPixels[i] &&
frame.NewPixels[i + 1] == frame.PreviousPixels[i + 1] &&
frame.NewPixels[i + 2] == frame.PreviousPixels[i + 2])
continue;
memoryStream.Write(BitConverter.GetBytes(i), 0, 4);//write the index.
memoryStream.WriteByte(frame.NewPixels[i]);
memoryStream.WriteByte(frame.NewPixels[i + 1]);
memoryStream.WriteByte(frame.NewPixels[i + 2]);
}
byte[] buff = compress(memoryStream.ToArray());//compress gzip.
SendVarData(buff);
}
}
處理和應用在對方的變化不是我的主要問題。 我真正的瓶頸是帶寬使用。在桌面上的一個小的變化,例如,當用戶使用右鍵點擊鼠標他並打開經典的菜單,發送的數據是(壓縮後!)約120〜150KB! 我真的喜歡去優化它。我不能讓我的程序通過網絡發送大量數據時,有隻有一個小的變化... 正如你看到的,我已經使用
一個gzip壓縮(其提供高壓縮比)。
只寫差異。
進出口尋找方法來優化網絡的想法...我會非常非常appreicate因爲即時通訊的任何傳入幫助打破我的頭相當長的時間,並試圖想想財產以後可以幫助...
謝謝。
聽起來很像一個簡單的RFB實現,你看着現有的開源VNC客戶端? –
有一件事你可以做的是「試」檢測連續色塊和發送「黑白200x100灰色矩形」這你可以在幾個字節,而不是60K(壓縮前) –