鏈接C#局域網(wǎng)桌面共享軟件制作(一)
如果你運行這個軟件查看流量監(jiān)控就會發(fā)現(xiàn)1~2M/s左右的上傳下載,并且有時會報錯“參數(shù)無效”,如果你將屏幕截圖保存到本地的話每張圖片大概4M(bmp)、120KB(jpg),按照1秒傳送10張圖片計算,可想而知網(wǎng)絡流量占用很大。下面我們將一一解決這些問題
1.壓縮客戶端圖片
壓縮函數(shù)(需using System.Drawing.Imaging;)
/// <summary> /// 壓縮圖片,將壓縮后的圖片存入MemoryStream /// </summary> /// <param name="bitmap">原圖片</param> /// <param name="ms">內(nèi)存流</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; }
客戶端線程執(zhí)行體改為
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.服務端報錯處理
“參數(shù)無效”錯誤原因是
byte[] b = new byte[1024 * 1000];hostSocket.Receive(b);MemoryStream ms = new MemoryStream(b);Image img=Image.FromStream(ms);//ms數(shù)據(jù)錯誤不能轉(zhuǎn)換為Image
為什么ms無效?原因是圖片大小超過了字節(jié)數(shù)組b的容量,或傳回的數(shù)據(jù)丟失或有空的內(nèi)容
解決方法:既然字節(jié)數(shù)組容量小了,我們就增大它的容量。如byte[] b = new byte[1024 * 10000];增加10倍
由于我們已經(jīng)在客戶端壓縮圖片了,所以就不用在考慮這點了。
另一點就是在將數(shù)據(jù)接收后判斷數(shù)據(jù)是否為一張圖片,如果不是就丟棄。
實現(xiàn)代碼
private bool getImage(MemoryStream ms,out Image image) { try { image = Image.FromStream(ms); return true; } catch { image = null; return false; } }
服務器線程執(zhí)行體改為
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)}循環(huán)接收數(shù)據(jù)以節(jié)省內(nèi)存分配吧.
需要說明的是:如果你還有更好的解決方法請分享給我們,當然這個程序還未完,上面只是解決問題的一些方法
轉(zhuǎn)載,請注明出處和相關鏈接,否則追究其法律責任!
新聞熱點
疑難解答