【问题标题】:Sending base64 string trough sockets doesnt completely arrive通过套接字发送 base64 字符串未完全到达
【发布时间】:2017-01-25 17:20:43
【问题描述】:

在我的应用程序中,我想实现个人资料图片,所以我从一张标准图片开始,我将其转换为字节数组,然后转换为 base64 字符串,但是当客户端从服务器请求字符串时它没有完全到达,服务器从数据库中读取整个字符串并将其发送给客户端,客户端只接收字符串的一部分,这是字符串(必须使用 pastebin):http://pastebin.com/ZmHhsZgG 这是客户端接收的字符串:iVBORw0KGgoAAAANSUhEUgAAAEA 这是服务器从数据库中获取它的方式:

public string GetPP(string user)
    {
        CONN = new MySqlConnection();
        CONN.ConnectionString = Config.CONNSTRING;
        string query = "select * from members where username='" + user + "'";
        try
        {
            CONN.Open();
            COMMAND = new MySqlCommand(query, CONN);
            READER = COMMAND.ExecuteReader();
            string p = null;
            while (READER.Read())
            {
                 return p = READER.GetString("profilepic");
            }
            return p;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return "";
        }
        finally
        {
            CONN.Dispose();
        }
    }

然后它发送它:

private void Do()
    {
        int requestCount = 0;
        byte[] bytesFrom = new byte[20025];
        string dataFromClient = null;
        Byte[] sendBytes = null;
        string serverResponse = null;
        string rCount = null;
        requestCount = 0;
        Responder.Responder R = new Responder.Responder();
        while ((true))
        {
            try
            {
                byte[] buffer = new byte[4];
                requestCount = requestCount + 1;
                NetworkStream networkStream = clientSocket.GetStream();
                buffer = new byte[4];
                int readBytes = networkStream.Read(buffer, 0, 4);
                if (readBytes == 0)
                    break;
                int MessageSize = BitConverter.ToInt32(buffer, 0);
                byte[] bufferreader = new byte[MessageSize];
                readBytes = networkStream.Read(bufferreader, 0, MessageSize);
                if (readBytes == 0)
                    break;
                dataFromClient = Encoding.ASCII.GetString(bufferreader);
                rCount = Convert.ToString(requestCount);
                byte[] outbuffer = new byte[4];
                serverResponse = R.Respond(dataFromClient);
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                outbuffer = new byte[4];
                outbuffer = BitConverter.GetBytes(sendBytes.Length);
                networkStream.Write(buffer, 0, 4);
                networkStream.Flush();
                networkStream.Write(sendBytes, 0, sendBytes.Length);
                networkStream.Flush();
            }
            catch (Exception ex)
            {
                Console.WriteLine(" >> " + ex.ToString());
            }
        }
        Console.WriteLine("User Server >> " + "Client No:" + Convert.ToString(clNo) + " Stopped!");
    }

而客户端收到:

            byte[] inbuffer = new byte[4];
            buffer = new byte[4];
            int readBytes = serverStream.Read(buffer, 0, 4);
            int MessageSize = BitConverter.ToInt32(buffer, 0);
            Console.WriteLine(Convert.ToString(MessageSize));
            byte[] bufferreader = new byte[MessageSize];
            readBytes = serverStream.Read(bufferreader, 0, MessageSize);
            string dataFromServer = Encoding.ASCII.GetString(bufferreader);
            if (dataFromServer.Contains("reauth"))
            {
                MessageBox.Show("Session Expired! Please Re-authenticate..");
                this.Close();
            }
            else
            {
                richTextBox1.Text = dataFromServer; //used to see what it receives
                MemoryStream mStream = new MemoryStream();
                byte[] pData = Convert.FromBase64String(dataFromServer);
                mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
                Bitmap bm = new Bitmap(mStream, false);
                mStream.Dispose();
                pictureBox1.Image = bm;
            }
            clientSocket.Close();

提前致谢

【问题讨论】:

  • 服务器代码中的变量“buffer”是什么?你能显示那个代码吗?
  • 是的,抱歉,附上该特定部分的完整代码
  • 您正在存储来自NetworkStream.Read() 的返回值,但您似乎认为所有内容都是在单个Read() 调用中收到的。您必须检查readBytes 的值并继续读取,直到读取足够的字节数。
  • 我以为我首先收到一条消息,告诉我真实消息的大小,以便它知道它有那么大,如果消息没有那么大,它不会抛出异常已知大小?
  • 当您将其转换为位图时,它很可能会引发异常,是的。但我的观点是,即使您知道要接收多少数据,也不能保证仅仅因为您提出请求就会收到所有数据。例如,您可能只获得前 3/4,因为单个 Read() 调用在大多数情况下不会接收您请求的所有数据。

标签: c# sockets tcp tcpclient networkstream


【解决方案1】:

我认为数据没有被完全读取,因为您作为长度指示器发送的“缓冲区”变量没有初始化为更新的值。我猜你想发送的是:

serverResponse = R.Respond(dataFromClient);
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
outbuffer = new byte[4];
outbuffer = BitConverter.GetBytes(sendBytes.Length);
**networkStream.Write(outbuffer , 0, 4);**
networkStream.Flush();
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();

【讨论】:

  • 他还希望在一个 Read() 电话中收到所有内容。你能在你的回答中也提到这一点吗? :)
  • 是的,你是对的,它现在可以工作了,该死的我真的很愚蠢,我怎么会错过它,但是谢谢你:)
  • 第一个获取大小,以便第二个知道它必须读取多少字节
  • 是的,但不可能在单个 Read() 调用中收到所有数据。必须检查Read() 的返回值(这就是它返回任何内容的原因)并继续阅读,直到您读取了所有您想要的数据。
  • 嗯,好的,谢谢,我也会这样做,问题会少一些:)
【解决方案2】:

NetworkStream.Read 方法返回成功读取的字节数。如果要读取整个数据,则必须读取多次。您可以尝试以下代码:

private int read(NetworkStream ns, Byte[] data_buffer)
    {
        int result = -1;

        const int kBufferSize = 1024 * 1024;
        Byte[] buffer = new Byte[kBufferSize];
        int read_size = 0;
        int real_read_size = 0;
        int read_length;
        int total_length;

        if (ns != null && data_buffer != null)
        {
            try
            {
                total_length = data_buffer.Length;
                read_size = 0;
                real_read_size = 0;
                read_length = 0;

                while (true)
                {
                    read_size = kBufferSize <= (total_length - read_length) ? kBufferSize : total_length - read_length;
                    //todo:if (ns.CanRead)
                    real_read_size = ns.Read(buffer, 0, read_size);


                    if (real_read_size > 0)
                    {
                        Array.Copy(buffer, 0, data_buffer, read_length, real_read_size);

                        read_length += real_read_size;

                        //Console.WriteLine("net Read " + read_length.ToString() + " byte!");

                        if (read_length >= total_length)
                        {
                            result = 0;
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine("net Read 0 byte!");
                        result = -1;
                        break;
                    }
                }



            }
            catch (IOException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }
            finally
            {

            }
        }

        return result;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多