TCP客户机/服务器图像传输 [英] TCP Client/Server Image Transfer

查看:159
本文介绍了TCP客户机/服务器图像传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图发送使用TCP套接字的图像。客户机连接到服务器,没有任何问题,并开始接收该数据。问题是,当我尝试流转换为使用FromStream()方法的图像,我得到一个内存不足的异常。任何人都可以帮我吗?真的很重要!这里是code;

I'm trying to send an image using a TCP socket. The client connects to the server without any problems and start to receive the data. The problem is when I try to convert the stream to an image using FromStream() method, I get an OutOfMemory Exception. Can anyone help me out? Really important!! Here is the code;



private void btnConnect_Click(object sender, EventArgs e)
        {
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            TcpClient client = new TcpClient();
        client.Connect(ipAddress, 9500);
        NetworkStream nNetStream = client.GetStream();

        while (client.Connected)
        {
            lblStatus.Text = "Connected...";
            byte[] bytes = new byte[client.ReceiveBufferSize];
            int i;
            if (nNetStream.CanRead)
            {
                nNetStream.Read(bytes, 0, bytes.Length);  

                Image returnImage = Image.FromStream(nNetStream); //exception occurs here
                pictureBox1.Image = returnImage;
            }
            else
            {
                client.Close();
                nNetStream.Close();
            }


        }
        client.Close();
    }


try
            {
                IPAddress ipAddress = Dns.Resolve("localhost").AddressList[0];
                TcpListener server = new TcpListener(ipAddress, 9500);
                server.Start();
                Console.WriteLine("Waiting for client to connect...");

                while (true)
                {
                    if (server.Pending())
                    {
                        Bitmap tImage = new Bitmap(Image URL goes here);
                        byte[] bStream = ImageToByte(tImage);

                        while (true)
                        {
                            TcpClient client = server.AcceptTcpClient();
                            Console.WriteLine("Connected");
                            while (client.Connected)
                            {
                                NetworkStream nStream = client.GetStream();
                                nStream.Write(bStream, 0, bStream.Length);
                            }
                        }
                    }
                }

            }


            catch (SocketException e1)
            {
                Console.WriteLine("SocketException: " + e1);
            }
        }
        static byte[] ImageToByte(System.Drawing.Image iImage)
        {
            MemoryStream mMemoryStream = new MemoryStream();
            iImage.Save(mMemoryStream, System.Drawing.Imaging.ImageFormat.Gif);
            return mMemoryStream.ToArray();
        }

感谢了很多先进的,

Thanks a lot in advanced,

推荐答案

有几件事情错了,其中可能包括你正在使用的协议。首先,客户端:

There are a couple of things wrong, including, possibly the protocol you are using. First, the client:

  • 如果您希望一个单一的形象,没有必要为,而循环
  • 您的客户端第一次做了其内容从服务器的某些信息到缓冲区中,然后调用 Image.FromStream(nNetStream)将读取数据不完整。
  • 当你从流中读取,请记住,一个呼叫不保证填写您的缓冲区。它可以返回一个介于0和您的缓冲区大小任意数目的字节。如果返回0,则意味着不存在更多的阅读。你的情况,这也意味着你的客户目前还没有办法知道有多少从服务器读取的。这里一个解决方案是让服务器发送的图像的长度作为第一块的信息。另一种解决方案是让服务器断开连接的客户端后,已发送的信息。这可能是你的情况可以接受的,但如果你需要永久连接(在客户端如连接池)将无法正常工作。
  • If you expect a single image, there is no need for the while loop
  • Your client first does a Read which reads some information from the server into the buffer, and then it calls Image.FromStream(nNetStream) which will read incomplete data.
  • Whenever you read from a stream, keep in mind that a single Read call is not guaranteed to fill your buffer. It can return any number of bytes between 0 and your buffer size. If it returns 0, it means there is no more to read. In your case this also means that your client currently has no way of knowing how much to read from the server. A solution here is to have the server send the length of the image as the first piece of information. Another solution would be to have the server disconnect the client after it has sent the information. This may be acceptable in your case, but it will not work if you need persistent connections (e.g. pooled connections on client side).

客户端应该是这个样子(假设它发送数据后,服务器将断开连接):

The client should look something like this (assuming the server will disconnect it after it sends the data):

IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
using (TcpClient client = new TcpClient())
{
    client.Connect(ipAddress, 9500);
    lblStatus.Text = "Connected...";

    NetworkStream nNetStream = client.GetStream();
    Image returnImage = Image.FromStream(nNetStream);
    pictureBox1.Image = returnImage;
}

接着,服务器

Next, the server:

  • 而不是挂起的,你可以简单地接受客户
  • 在服务器发送数据流一遍又一遍给同一个客户端,直到它们断开连接。相反,只有一次发送。
  • Instead of Pending, you can simply accept the client
  • The server sends the stream over and over again to the same client, until they disconnect. Instead, send it only once.

服务器循环应该是这个样子:

The server loop should look something like this:

Bitmap tImage = new Bitmap(Image URL goes here);
byte[] bStream = ImageToByte(tImage);

while (true)
{
    // The 'using' here will call Dispose on the client after data is sent.
    // This will disconnect the client
    using (TcpClient client = server.AcceptTcpClient())
    {
        Console.WriteLine("Connected");
        NetworkStream nStream = client.GetStream();

        try
        {
            nStream.Write(bStream, 0, bStream.Length);
        }
        catch (SocketException e1)
        {
            Console.WriteLine("SocketException: " + e1);
        }
    }
}

这篇关于TCP客户机/服务器图像传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆