4

i am new to the C# world. I am using it for fast deployment of a solution to capture a live feed which comes in this form (curly brackets for clarity): {abcde}{CompressedMessage}, where {abcde} constitutes 5 characters indicating the length of the compressed message. The CompressedMessage is compressed using XCeedZip.dll, and needs to be uncompressed using the dll's uncompress method. The uncompress method returns an integer value indicating success or failure (of various sorts, eg no license failure, uncompression failure etc). I am receiving failure 1003 http://doc.xceedsoft.com/products/XceedZip/ for reference of the return values from the uncompress method.

while(true){    
byte[] receiveByte = new byte[1000];
sock.Receive(receiveByte);
string strData =System.Text.Encoding.ASCII.GetString(receiveByte,0,receiveByte.Length);
string cMesLen = strData.Substring(0,5); // length of compressed message;
string compressedMessageStr = strData.Substring(5,strData.Length-5);
byte[] compressedBytes = System.Text.Encoding.ASCII.GetBytes(compressedMessageStr);
//instantiating xceedcompression object     
XceedZipLib.XceedCompression obXCC = new XceedZipLib.XceedCompression();
obXCC.License("blah");
// uncompress method reference http://doc.xceedsoft.com/products/XceedZip/
// visual studio displays Uncompress method signature as Uncompress(ref object vaSource, out object vaUncompressed, bool bEndOfData)
object oDest;
object oSource = (object)compressedBytes;
int status = (int) obXCC.Uncompress(ref oSource, out oDest, true);
Console.WriteLine(status); /// prints 1003 http://doc.xceedsoft.com/products/XceedZip/
}                                                       

So basically my question boils down to invocation of the uncompress method and correct way of passing the parameters. I am in unfamiliar territory in the .net world, so i won't be surprised if the question is really simplistic.

Thanks for replies ..

##################################### updates

I am now doing the following:

int iter = 1;
int bufSize = 1024;
byte[] receiveByte = new byte[bufSize];
while (true){
  sock.Receive(receiveByte);
  //fetch compressed message length;
  int cMesLen = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(receiveByte,0,5));
  byte[] cMessageByte = new byte[cMesLen];
  if (i==1){
    if (cMesLen < bufSize){
      for (int i = 5; i < 5+cMesLen; ++i){
        cMessageByte[i-5] = b[i];
      }
    }
  }
  XceedZipLib.XceedCompression obXCC = new XceedZipLib.XceedCompression();
  obXCC.License("blah");
  object oDest;
  object oSource = (object) cMessageByte;
  int status = (int) obXCC.Uncompress(ref oSource, out oDest, true);
  if (iter==1){
    byte[] testByte = objectToByteArray(oDest);
    Console.WriteLine(System.Text.Encoding.ASCII.GetString(testByte,0,testByte.Length));
  }      
}

private byte[] objectToByteArray(Object obj){
  if (obj==null){
    return null;
  }
  BinaryFormatter bf = new BinaryFormatter();
  MemoryStream ms = new MemoryStream();
  bf.Serialize(ms,obj);
  return ms.ToArray();
}

Problem is the testByte writeline command prints out gibberish. Any suggestions on how to move forward on this ? the status variable of uncompress is good and equal to 0 now.

4

1 回答 1

3

第一个错误始终是没有查看 ; 的返回值Receive。您不知道您刚刚阅读了多少数据,也不知道它是否构成了整个消息。

在我看来,您可能通过将整个数据视为 ASCII 来破坏消息有效负载。GetString与其对整个缓冲区执行 a ,不如GetString 指定仅使用 5 bytes

正确流程:

  • 继续调用Receive(缓冲数据,或增加偏移量并减少计数),直到您至少有 5 个字节
  • 处理这 5 个字节以获得有效负载长度
  • 继续调用Receive(缓冲数据,或增加偏移量并减少计数),直到您至少具有有效负载长度
  • 无需转换为/从 ASCII 即可处理有效负载
于 2012-07-06T06:33:00.867 回答