• 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)}循环接收数据以节省内存分配吧.

    需要说明的是:如果你还有更好的解决方法请分享给我们,当然这个程序还未完,上面只是解决问题的一些方法

    转载,请注明出处和相关链接,否则追究其法律责任!

  • 相关阅读:
    WP8.1 UI 编程 四、图形
    分治法 全排列问题的一个Java实现
    合并排序算法时间复杂度分析
    js如何实现复制粘贴功能
    关于<meta name="applicable-device"content="pc">
    ready
    css文字强制大写输入
    关于input,button标签在苹果手机上显示阴影解决办法
    【C#】中用if判断值是否是否为空
    视频格式MP4,需要转码
  • 原文地址:https://www.cnblogs.com/liuxiaobo93/p/3675466.html
Copyright © 2020-2023  润新知