将图像字节写入套接字然后读取它们时出现问题



我有一个java客户端(android)和c#服务器。Java 客户端使用以下代码段写入服务器映像的字节:

DataOutputStream output = new DataOutputStream(socket.getOutputStream());
if(startup)
{
    output.writeUTF("#" + message + "#");
    output.flush();
    startup = false;
}
else
if (Integer.parseInt(chatMessagesList.get(chatMessagesList.size() - 1)[2]) == MESSAGE_TYPE_FILE || Integer.parseInt(chatMessagesList.get(chatMessagesList.size() - 1)[2]) == MESSAGE_TYPE_IMAGE) {
    String imageName = chatMessagesList.get(chatMessagesList.size() - 1)[1];
    imageName = imageName.substring(imageName.lastIndexOf("/") + 1);
    Bitmap bm = BitmapFactory.decodeFile(chatMessagesList.get(chatMessagesList.size() - 1)[1]);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    output.writeUTF("#image:" + imageName + "|bytes:" + imageBytes.length + "#"); //METADATA
    output.flush();
    output.write(imageBytes); //IMAGE ITSELF
    output.flush();
} else {
    output.writeUTF("#" + message + "#");
    output.flush();
}

现在这是我的服务器代码(C#):

if(messsage.StartsWith("image:"))
{
    string imageName = messsage.Substring(messsage.IndexOf("image:") + "image:".Length);
    imageName = imageName.Substring(0, imageName.IndexOf("|bytes:"));
    string temp = messsage.Substring(messsage.IndexOf("|bytes:") + "|bytes:".Length);
    int bytesCount = int.Parse(temp);
    byte[] buff = new byte[bytesCount];
    int bytesReceived = client.Receive(buff);
    while(bytesReceived < buff.Length)
    {
        bytesReceived += client.Receive(buff);
        Console.WriteLine("bytes received: " + bytesReceived + "/" + buff.Length);
    }

    //            MemoryStream ms = new MemoryStream(buff);
    using (var ms = new MemoryStream(buff))
    {
        Image img = Image.FromStream(ms); //Breaks at this line with the exception* below
        img.Save(clientID + "/files/" + imageName);
        ms.Dispose();
        img.Dispose();
    }
    //           File.WriteAllBytes(clientID + "/files/" + imageName, buff);
}

我得到的例外:

System.ArgumentException was unhandled
  HResult = -2147024809
  Message = The parameter is invalid.
  Source = System.Drawing
  StackTrace:
       In System.Drawing.Image.FromStream (Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData)
       In System.Drawing.Image.FromStream (Stream stream)
       In the CloudServer.Program. <> C__DisplayClass4_0. <Main> b__0 () in D:  Visual Studio Projects  CloudServer  CloudServer  Program.cs: Line 148
       In System.Threading.ThreadHelper.ThreadStart_Context (Object state)
       In System.Threading.ExecutionContext.RunInternal (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       In System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       In System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state)
       In System.Threading.ThreadHelper.ThreadStart ()
  InnerException:

我已经用谷歌搜索了这个问题,我知道这是因为MemoryStream只包含 1 张以上图像的数据,或者与图像字节无关的数据。

此代码不正确:

byte[] buff = new byte[bytesCount];
int bytesReceived = client.Receive(buff);
while(bytesReceived < buff.Length)
{
    bytesReceived += client.Receive(buff);
}

如果您以块的形式接收图像字节(很可能) - 您的 client.Receive(buff) in while 循环将从 0 开始写入buff,覆盖您在上一帧中收到的数据。你想这样做:

while(bytesReceived < buff.Length)
{
    bytesReceived += client.Receive(buff, bytesReceived, buff.Length - bytesReceived, SocketFlags.None);
}

最新更新