2013-10-12 82 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