Отправка строки base64 через сокет c # - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь отправить изображение в кодировке 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».

Как решить эту проблему? Большое спасибо!

1 Ответ

0 голосов
/ 27 апреля 2018

received сообщает , сколько байтов в буфере в настоящее время допустимо . Перегрузка GetString, которую вы используете, преобразует все байтов в буфере.

Вы можете перейти к передаче явного индекса и подсчета:

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

Также обратите внимание, что эта техника, которую вы используете , не является в целом безопасной, но должна быть для подмножества символов base-64. Не все символы UTF-8 занимают один байт, и TCP не дает никаких гарантий, что вы не получите только часть символа, возвращаемого одним вызовом Receive, тогда как оставшиеся байты этого символа будут доставлены (надеюсь 1 ) по следующему звонку.

(И комментарий Мэтью о том, что все это довольно странно, поскольку вы тоже можете просто отправить байты напрямую)


1 Я не имею в виду, что байты будут потеряны. Просто здесь есть несколько гарантий, поэтому вы не гарантируете, что следующий вызов получит всех оставшихся байтов для символа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...