小弟最近在写一个远程桌面监控的程序,刚才发了一帖问解决了一个问题,可是程序还是不是不能正常运行但是不是同一个问题所以再开一帖
大体思路是 在服务端截取下桌面图片保存入 TCPListener创建的 NetWorkStream中 不断发送,两次间用标识符标识 
在客户端 通过TcpClient的NetWorkStream读取字节数组先保存在一个临时的文件中 然后再加载到 picturebox中 
可问题出来了。代码如下~ 
服务端:
        TcpClient client;
        NetworkStream stream;
        private void Start()
        {
            TcpListener listener = new TcpListener(IPAddress.Any, Properties.Settings.Default.Port);
            listener.Start();
            client = listener.AcceptTcpClient();
            stream = client.GetStream();
        }        private void timer1_Tick(object sender, EventArgs e)
        {
            Bitmap bitmap = null;
            bitmap = CutDesk();  //截取到图片
            bitmap.Save(stream, ImageFormat.Jpeg); //直接保存到流中
            byte[] flag = Encoding.ASCII.GetBytes("<FLAG>");  //写入分隔符
            stream.Write(flag, 0, flag.Length);
        }客服端
        public byte[] temp = null;  //临时放部分字节数组 
        private void GetPictureBox() 
        { 
            if (File.Exists(Application.StartupPath + "\\temp.jpeg")) 
                File.Delete(Application.StartupPath + "\\temp.jpeg"); 
            byte[] bs = new byte[4096]; 
            int readSize = 0; 
            FileStream fs = File.OpenWrite(Application.StartupPath + "\\temp.jpeg"); 
            while (true) 
            { 
                readSize = netstream.Read(bs, 0, 4096); 
                string str = new string(Encoding.ASCII.GetChars(bs)); 
                string[] strs = str.Split(new string[] { " <FLAG>" },
                                          StringSplitOptions.RemoveEmptyEntries); 
                if (strs.Length == 1) 
                { 
                    if (temp != null) 
                    { 
                        fs.Write(temp, 0, temp.Length); 
                            fs.Flush();  //通过刚才那贴解决了不能写入的问题
                        temp = null; 
                    } 
                    fs.Write(bs, 0, readSize);  //可以成功写入 
                } 
                else 
                { 
                    fs.Write(Encoding.ASCII.GetBytes(strs[0].ToCharArray()), 0, strs[0].Length); 
                    temp = Encoding.ASCII.GetBytes(strs[1].ToCharArray()); 
                    fs.Close(); 
                    break; 
                } 
            } 
        private void timer1_Tick(object sender, EventArgs e)
        {
            using (Stream filestream = File.OpenRead(Application.StartupPath + "\\temp.jpeg"))
            {
                pictureBox1.Image = Image.FromStream(filestream);
            }
        }
但是第二次接收到的图片发生错误不能正常打开,第一次接收到的图片是正常的,所以不知道该怎样写了
或者能够让pictureBox直接通过流读取…… 以上程序出来什么问题,或者还有其他的解决方案
还请达人帮忙解答~

解决方案 »

  1.   

    可能大家看不懂我用temp的思路
    我是想通过发送 服务端发送 <图片字节流> + <FLAG>标识 区分每张图片,到了客户端 接收流,因为我担心网络速度,所以在流中部一定就只有一张图片,所以想通过分隔标识区分 两张图片的边界,然后把<FLAG>前面的保存一张图片 后面的先放入temp中,第二次先将temp中的字节数组写入文件中,再继续写入此次得到的数据得到完整的图片数据。不知道有没有其他更直接的方法……
      

  2.   

    好像在客服端 直接运行
    pictureBox1.Image = Image.FromStream(netstream);
    是不可行的……
      

  3.   

    啊,通过断点跟踪,我在服务端重新加了个按键,按一下发一张
    然后我在客服端处跟踪的时候发现第一次接收到了图片后 temp内竟然有几千个字节……,按理来说我发送一张,在<FLAG>后面应该没有字节流才是啊,怎么接收过来依然在<FLAG>后面还有这么多字节……
      

  4.   

    说一下GetPictureBox你是怎么调用的
      

  5.   

    GetPictureBox?
    就是 直接用
    using (Stream filestream = File.OpenRead(Application.StartupPath + "\\temp.jpeg")) 
                { 
                    pictureBox1.Image = Image.FromStream(filestream); 
                }
    来取得,把流中字节保存到文件中,下次接收前再把这个给删除掉
    我的思路是这样的,不知道能不能在流中就直接获取
      

  6.   

    在网络中,由于网速不定因素,在流中肯能会有不知一张图片 或者是2.5个 不完整的图片
    …部分数据…<START>…完整数据…<FLAG>…部分数据…
    那在<START><FLAG>之前和之后的数据应该怎么保存? 
      

  7.   

    我好像明白你的意思了
    那如果出现这种情况呢?
    …部分数据…<FLAG>…部分数据…<START>…部分数据…
    没有完整的数据<FLAG> 前面的是部分数据<START>后面的也是部分数据
    这种情况应该怎么办?
      

  8.   

    或者说有没有办法直接冲流中加载到pictureBox里去呢?
      

  9.   

    直接通过流加载到picturebox的方法非常不好,会受通信状况的影响
      

  10.   

    看来原先的接收思路有点问题
    我现在改掉了服务端的发送方式,采用应答式的,当接收到客户端发送来的指令后才发送图片信息,并且直接保存到流中,不再加什么分隔符了,这样在流当中始终只有一张图片的信息。然后在客户端接收方式中时刻检测接收到的数据,直接保存到memoryStream中,这样就直接通过 pictureBox.image=image.fromstream(memtroyStram)来获取图片流。暂时搞定……测试下 结帐