【问题标题】:Sending base64 string via socket c#通过套接字c#发送base64字符串
【发布时间】:2018-04-27 20:42:41
【问题描述】:

我正在尝试发送 base64 编码的图像。

客户端代码:

private void button1_Click(object sender, EventArgs e)
    {
        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        client.Connect(ipEndPoint);
        Bitmap printScreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics g = Graphics.FromImage(printScreen as Image);
        g.CopyFromScreen(0, 0, 0, 0, printScreen.Size);
        MemoryStream ms = new MemoryStream();
        printScreen.Save(ms, ImageFormat.Jpeg);
        client.Send(Encoding.UTF8.GetBytes(Convert.ToBase64String(ms.ToArray())));
        client.Shutdown(SocketShutdown.Both);
    }

服务器代码:

const int BUFFER_SIZE = 2048;
static byte[] buffer = new byte[BUFFER_SIZE];
static void ReceiveCallback(IAsyncResult AR)
    {
        Socket current = (Socket)AR.AsyncState;
        int received = current.EndReceive(AR);
        if (received > 0)
        {
            s += Encoding.UTF8.GetString(buffer);
            current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
        } else
        {
            Console.WriteLine(s.Length);
            var bytes = Convert.FromBase64String(s);
            using (var imageFile = new FileStream("test.jpg", FileMode.Create))
            {
                imageFile.Write(bytes, 0, bytes.Length);
                imageFile.Flush();
            }
            s = "";
        }
    }

但图片通常不会传输。 通常会出现这个错误: “输入数据不是有效的 Base-64 字符串”。

如何解决这个问题? 非常感谢!

【问题讨论】:

  • 为什么? Base64 不仅仅是发送它编码的字节。
  • 当您可以发送原始二进制数据时,为什么还要发送 base64?
  • 我知道。只是具体的任务。

标签: c# sockets base64


【解决方案1】:

received 告诉您缓冲区中有多少字节当前有效。您正在使用的GetString 的重载会转换缓冲区中的所有 个字节。

您可以切换到传递显式索引和计数:

s += Encoding.UTF8.GetString(buffer,0,received);

另外请注意,您使用的这种技术并不通常是安全的,但应该适用于 base-64 字符子集。并非所有 UTF-8 字符都占用一个字节,并且 TCP 不能保证您不会只获得由一次调用 Receive 返回的字符的部分,而该字符的剩余字节将是下一次通话时已送达(希望1)。

(马修关于这一切的评论很奇怪,因为你也可以直接发送字节)


1我在这里并不是说字节会丢失。只是这里提供的保证很少,因此您不能保证下一次调用将收到该字符剩余的所有字节。

【讨论】:

  • 它在 OP 的示例中有效,因为 base64 仅使用 ASCII 字符,但通常您不应在每次接收时解码 UTF-8 数据,请确保您已完成接收所有 UTF-8首先是字节,然后一次解码(除非您使用流式解码器,您可以在接收字节时将其推入其中 - Encoding 类不是流式解码器)。在 OP 的示例中,数据的 EOF 是断开连接,因此将接收到的字节按原样附加到不断增长的 byte[] 缓冲区或流中,然后仅在达到断开连接时才在该缓冲区/流上调用 Encoding.UTF8.GetString()
猜你喜欢
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
相关资源
最近更新 更多