2013-10-12 4 views
3

렌더링 응용 프로그램에 연결되어 있고 dismally 실패하는 C# 클라이언트를 작성하고 있습니다!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

첫 번째 인수가 그 가장 가능성이 문제 팩을 ... 내가 생각하는 방법을 알려줍니다

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#에서

그것 (''

+0

추가 참조 - http://stackoverflow.com/questions/1818242/c-sharp-equivalent-of -python-struct-pack – Wolfwyrd

답변

3

struct.pack을 살 수있는 의지를 잃고 나의 이해에서 은 다음 형식을 취 형식에 따라 압축되는 일련의 값입니다. 귀하의 질문에 당신은 전화 : 말하는

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

"오랫동안 같은 포장 제로 다음에 리틀 엔디안으로이 메시지의 길이를 포장 조금 엔디안 긴 내 메시지의 나머지 부분을 추가하여 다음에".

C#에서 이러한 종류의 문제에 접근하면 불행히도 struct.pack의 직접 포트가 없습니다.

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

또는 MemoryStreamBinaryWriter를 사용 : 당신의 가장 가까운 상당처럼 중 하나 BitConverter 일회성의 전환을 사용하는 것입니다. 이것은 또 다른 문제를 야기하지만, 이러한 도구를 사용하여 엔디안을 제어 할 수는 없습니다. 그들은 "IsLittleEndian"을 폭로하여 그들이 어떻게 행동하는지 알지만 변경할 수는 없습니다.

존 소총 그러나 경우에 - 그의 MiscUtils 라이브러리는 사용할 수 있습니다 또는 EndianBinaryWriter 당신이 작가/MemoryStream을의 경로를 이동해야 LittleEndianBitConverter (MiscUtil.Conversion.LittleEndianBitConverter)가 포함되어 있습니다. 그래서 모두 함께 퍼팅 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를 기본 유형의 가장 효율적인 복사 방법으로 사용합니다.

* 편집 * 나는 Python codeequivalent in C#에 대한 IDEOne의 문제의 예를 촬영하고 빠른 스크립트를 조롱 한

. 여기서 키커는 Struct.Pack('<l', 0) 호출이 바이트를 무시하고 출력에 추가하지 않으므로 사용자를 트립하는 것일 수 있습니다. 이로 인해 출력이 8 바이트가 너무 길어졌습니다.

해당 스크립트는 올바른 방향으로 사용자를 안내해야합니다. 그래도 문제가 해결되지 않으면 시도한 코드를 게시 할 수 있습니다.참고로

, 파이썬에서 완성 된 코드 :

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# 버전을 테스트하는 누군가가 참여할 것으로 생각됩니다. 그들이 사용하지 않을 100meg 앱. 적어도 내가 대답을 찾을 때까지 파이썬 하나 프로토 타입을 가지고 :) – NigeC

+0

당신의 도움을 주셔서 감사합니다, 그것의 마침내 작동 – NigeC