2013-10-12 97 views
3

我正在构建一个C#客户端,它连接到一个呈现应用程序并且失败! 我缩小了问题下通过解剖一个Python客户端,它工作于这一行:Struct.Pack相当于C#

def Startclient_Click(self, sender, e): 
     try: 
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      s.connect((host, int(port))) 
      message = b'message "Render"' 
      msg = struct.pack('<l',len(message))+struct.pack('<l',0)+message 
      #print(msg)    
      s.sendall(msg) 
      data = s.recv(1024)  

      data.decode("utf-8")   
      self.datatxt.Text ="data: " +str(data) 
      s.close() 

      return 
     except: 
      self.datatxt.Text ="No Server Connection" 
      return 

就相当于在C#是什么? 从我的理解它的消息之前,需要8个字节

对不起,愚蠢的问题,但我一直在这几天,我失去了生活 感谢

+0

的第一个参数告诉它该办法收拾这是你最有可能的问题......我认为(''

+0

有关其他参考 - http://stackoverflow.com/questions/1818242/c-sharp-equivalent-of -pythons-struct-pack – Wolfwyrd

回答

3

struct.pack意志需要的格式,然后一系列值将根据格式打包。在你的问题,你拨打:

struct.pack('<l', len(message))+struct.pack('<l',0)+message 

这是说:“收拾这个消息的长度为小尾数长,然后包装成一个零little-endian的长随后追加我的消息的休息”。

当您在C#中处理这类问题时,我们很遗憾没有直接使用struct.pack。你最接近的将是使用一个BitConverter为一次性转换,如:

BitConverter.GetBytes((long)message.length) + BitConverter.GetBytes(0l) + message 

或使用BinaryWriterMemoryStream。这带来了另一个问题,但是你不能使用这些工具来控制字节顺序。他们揭露“IsLittleEndian”,所以你知道他们是如何行事,但你不能改变它。然而

乔恩斯基特接通的情况下 - 他MiscUtils库包含LittleEndianBitConverter(MiscUtil.Conversion.LittleEndianBitConverter),您可以使用或EndianBinaryWriter应该你去的作家/ MemoryStream的路线。所以,把他们放在一起,引用MiscUtil库,并使用类似:

var bytes = new List<byte[]>(new[] 
    { 
     LittleEndianBitConverter.GetBytes(message.LongLength), 
     LittleEndianBitConverter.GetBytes(0l), 
     message 
    }); 

var msg = new byte[bytes.Sum(barray => barray.LongLength)]; 
int offset = 0; 
foreach (var bArray in bytes) 
{ 
    System.Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length); 
    offset = bArray.Length; 
} 

的代码是未经测试,但应该给你一个合理的起点。假设你的消息已经是一个字节数组,并且msg是你想要返回的数组。我们使用System.Buffer.BlockCopy,因为它是原始类型的最有效的复制方法。

*编辑*

我已经采取的例子中的问题,并嘲笑了一个快速的脚本IDEOnePython codeequivalent in C#。这里的踢球者是Struct.Pack('<l', 0)调用忽略了这个字节,并且不会将它添加到输出中,这可能会让你感到沮丧。这导致输出为8个字节太长。

这些脚本应该指向正确的方向。如果您仍然遇到问题,可以发布您尝试过的代码。

仅供参考,最终的程序代码在Python:

import struct 
message = b'message "Render"' 
msg = struct.pack('<l',len(message)) + struct.pack('<l',0) + message 
print(":".join("{0:x}".format(ord(c)) for c in msg)) 

而在C#:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using MiscUtil.Conversion; 

public class Test 
{ 
    public static void Main() 
    { 
     var message = Encoding.ASCII.GetBytes("message \"Render\""); 

      var lenc = new LittleEndianBitConverter(); 

      var bytes = new List<byte[]>(new[] 
      { 
       lenc.GetBytes(message.LongLength), 
       message 
      }); 

      var msg = new byte[bytes.Sum(barray => barray.LongLength)]; 
      int offset = 0; 
      foreach (var bArray in bytes) 
      { 
       Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length); 
       offset = bArray.Length; 
      } 

      Console.WriteLine(BitConverter.ToString(msg).Replace("-", ":")); 
    } 
} 
+0

感谢您的回复,一旦我有机会尝试,我会尽快回复您:) – NigeC

+0

我仍然有可悲的问题,我已经更新了我的原始帖子与工作wpf ironpython版本,说实话,我认为它会涉及某人测试与Thea渲染C#版本,我不希望任何人下载100美元的应用程序,他们永远不会使用。至少我有Python的一个做一些原型,直到我找到答案:) – NigeC

+0

感谢您的帮助,它终于工作 – NigeC