C#局域網桌面共享軟件制作(二)


鏈接C#局域網桌面共享軟件制作(一)

如果你運行這個軟件查看流量監控就會發現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)}循環接收數據以節省內存分配吧.

 

需要說明的是:如果你還有更好的解決方法請分享給我們,當然這個程序還未完,上面只是解決問題的一些方法

轉載,請注明出處和相關鏈接,否則追究其法律責任!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM