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

时间:2017-11-03 17:47:04

标签: c# android sockets

我有一个java客户端(android)和c#server。 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张图片的数据,或者与图片的字节无关的数据。< / p>

1 个答案:

答案 0 :(得分:1)

此代码不正确:

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

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

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