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

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

问题描述

我正在尝试使用 TCP 套接字发送图像.客户端连接到服务器没有任何问题并开始接收数据.问题是当我尝试使用 FromStream() 方法将流转换为图像时,我得到了 OutOfMemory 异常.谁能帮我吗?真的很重要!!这是代码;

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();
        }

非常感谢,

推荐答案

有几个问题,可能包括您使用的协议.一、客户端:

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

  • 如果您期望单个图像,则不需要 while 循环
  • 您的客户端首先执行 Read,它将一些信息从服务器读取到缓冲区中,然后它调用 Image.FromStream(nNetStream) 将读取不完整的数据.
  • 当您从流中读取数据时,请记住,单个 Read 调用并不能保证会填满您的缓冲区.它可以返回 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;
}

接下来,服务器:

  • 您可以简单地接受客户端
  • ,而不是 Pending
  • 服务器一遍又一遍地将流发送到同一个客户端,直到它们断开连接.而是只发送一次.

服务器循环应该如下所示:

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天全站免登陆