如果你運行這個軟件查看流量監控就會發現1~2M/s左右的上傳下載,並且有時會報錯“參數無效”,如果你將屏幕截圖保存到本地的話每張圖片大概4M(bmp)、120KB(jpg),按照1秒傳送10張圖片計算,可想而知網絡流量占用很大。下面我們將一一解決這些問題
1.壓縮客戶端圖片
壓縮函數(需using System.Drawing.Imaging;)
/// <summary> /// 壓縮圖片,將壓縮后的圖片存入MemoryStream /// </summary> /// <param name="bitmap">原圖片</param> /// <param name="ms">內存流</param> public void CompressImage(Bitmap bitmap, MemoryStream ms) { ImageCodecInfo ici = null; Encoder ecd = null; EncoderParameter ept = null; EncoderParameters eptS = null; try { ici = this.getImageCoderInfo("image/jpeg"); ecd = Encoder.Quality; eptS = new EncoderParameters(1); ept = new EncoderParameter(ecd, 10L); eptS.Param[0] = ept; bitmap.Save(ms, ici, eptS); } catch (Exception ex) { throw new Exception(ex.Message); } finally { ept.Dispose(); eptS.Dispose(); } } /// <summary> /// 獲取圖片編碼信息 /// </summary> /// <param name="coderType">編碼類型</param> /// <returns>ImageCodecInfo</returns> private ImageCodecInfo getImageCoderInfo(string coderType) { ImageCodecInfo[] iciS = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo retIci = null; foreach (ImageCodecInfo ici in iciS) { if (ici.MimeType.Equals(coderType)) retIci = ici; } return retIci; }
客戶端線程執行體改為
private void threadimage() { try { while (true) { MemoryStream ms = new MemoryStream(); CompressImage(GetScreen(), ms);//很明顯傳引用 byte[] b = ms.ToArray(); sendsocket.Send(b); Thread.Sleep(100); } } catch (Exception ee) { MessageBox.Show(ee.Message); return; } }
好了壓縮后的圖片只有38k左右
2.服務端報錯處理
“參數無效”錯誤原因是
byte[] b = new byte[1024 * 1000]; hostSocket.Receive(b); MemoryStream ms = new MemoryStream(b); Image img=Image.FromStream(ms);//ms數據錯誤不能轉換為Image
為什么ms無效?原因是圖片大小超過了字節數組b的容量,或傳回的數據丟失或有空的內容
解決方法:既然字節數組容量小了,我們就增大它的容量。如byte[] b = new byte[1024 * 10000];增加10倍
由於我們已經在客戶端壓縮圖片了,所以就不用在考慮這點了。
另一點就是在將數據接收后判斷數據是否為一張圖片,如果不是就丟棄。
實現代碼
private bool getImage(MemoryStream ms,out Image image) { try { image = Image.FromStream(ms); return true; } catch { image = null; return false; } }
服務器線程執行體改為
private void trreadimage() { try { while (true) {byte[] b = new byte[1024 * 1000]; hostSocket.Receive(b); MemoryStream ms = new MemoryStream(b); Image img; if (getImage(ms, out img)) { picReceive.Image = img; } } } catch (Exception ee) { MessageBox.Show(ee.Message); thread.Abort(); } }
應該不會有人問為什么不用
int len=0;
byte[] b = new byte[1024];
while((len=hostSocket.Receive(b))>0)
{ms.write(b,0,b.lenth)}循環接收數據以節省內存分配吧.
需要說明的是:如果你還有更好的解決方法請分享給我們,當然這個程序還未完,上面只是解決問題的一些方法
轉載,請注明出處和相關鏈接,否則追究其法律責任!