2009-08-25 2 views
1

, 클라이언트는 다음을 수행합니다 ,받는 쪽 끝에서, 멤버 (cCommand 및 sPatameter)에 액세스 할 수 있도록 temp (byte [])를 STRUCT 또는 이와 동등한 것으로 다시 변환해야합니다. 그러나이 시점에서 진행 방법에 대한 단서가 없습니다. 실제 구조체 일 필요는 없습니다. 데이터 자체를 추출하면됩니다.[C#을] 내가 서버 (C#을)에 클라이언트 (C++)에서 데이터를 전송하는 명명 된 파이프를 사용하고

주 - 구조 메시지는 내가 생각해 낸 것입니다. 즉, 다른 형식이 재구성에 도움이 될 경우 (예를 들어 sParameter의 길이를 추가해도됩니까?), COMMAND 및 PARAMETER가 필요합니다. 단일 블럭 (가능한 경우)으로 전송되어야합니다.

요구 사항은 간단합니다 : 이 - COMMAND 행동이 수행에 필요한 사항을 나타내는 고정 길이 8 자 문자열 - 매개 변수가 가변 길이 각 명령에 따라 매개 변수 (이 문제가 발생하지 않는 한)

: COMMAND = TRANS

PARAMETER = C : \ file.txt를 C : \ NewFolder file.txt를 \

(이, 많은 애플리케이션 단지 설명하기 위해 존재한다)

가능하면 데이터 덩어리 (byte [])로 추출한 다음 분해 할 수있는 응용 프로그램에 전달하고 크기를 읽은 다음 필드를 읽은 다음 크기, 다음 필드 - 내 커뮤니케이션이 지나치게 구현과 연결되어야합니다.

이 전송을 구현하는 더 적합한 방법이 있다면 알려 주시기 바랍니다 ... 조언을 환영 할 것입니다. 도움이 될 것입니다. 감사합니다,

답변

1

를 사용하는 것이 더 간단 할 것 C++에서는이를 C#으로 정의 할 수 있습니다 (약간의 재귀가 필요할 수도 있음). 그런 다음 소켓의 크기를 읽은 다음 Marshal.PtrToStructure을 사용하여 C# 정의 된 구조로 마샬링합니다.

/* Define you structure like this (possibly) */ 
struct MESSAGE 
{ 
    [MarshalAs(UnmanageType.ByValArray, SizeConst=8)] 
    byte[] cCommand; 
    [MarshalAs(UnmanagedType.LPStr)] 
    string sParameter; 
}; 

/* Read data into an instance of MESSAGE like this */ 
byte[] bytes = new byte[Marshal.SizeOf(MESSAGE)]; 

socket.Receive(bytes, 0, bytes.Length); 
IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); 

try 
{ 
    Marshal.Copy(bytes, 0, ptr, bytes.Length); 
    m = (MESSAGE)Marshal.PtrToStructure(ptr, typeof(MESSAGE)); 
} 
finally 
{ 
    Marshal.FreeHGlobal(ptr); 
} 
+0

그것은 가변 길이 문자열 (sParameter)에서도 작동합니까? – Shaitan00

+1

MESSAGE 구조체에 다른 MarshalAs 특성을 추가했지만 작동해야합니다. – scottm

+0

귀하의 전문적 의견으로는 - 이것을하는 좋은 방법입니까? 내가 말했듯이 STRUCT는 좋은 선택이 될 것이라고 생각했기 때문에 STRUCT를 만들었지 만 내 문제를 해결할 수있는 더 좋은 방법이 있다면 나는 모든 귀입니다. ... – Shaitan00

1

플랫폼간에 데이터를 전달하기위한 제안 - 직접 직렬화/직렬화를 수행하지 마십시오. Google의 Protocol Buffers과 같은 도서관은 더 안전한 내기가 될 것입니다.

편집 : 효율적인 회선을 통한 표현이 중요하지 않은 경우, 당신이 구조체의 정의가있는 경우 JSON (C 예 : C 번호 Json.NETJsonCpp ++)

+2

질문에 C#으로 태그가 지정되었으므로 다음은 .NET 구현 링크입니다. http://code.google.com/p/protobuf-net/ 및 http : /code.google.com/p/protobuf-csharp-port/ –

+0

원래 C++ 응용 프로그램이 소켓에 바이트 배열을 전송하는 것과 같이 아무 것도 직렬화하지 않는 것처럼 들립니다.프로토콜 버퍼는 좋은 도구이지만, 나는 이런 식으로 약간 과잉이라고 생각한다. – scottm

+0

scottm, 나에게 8 문자 + 문자열 인스턴스를 보내는 것처럼 보입니다. 구조체의 바이트를 복사하면 거의 실패합니다. 직렬화가 중요하다고 생각합니다. – orip

0

당신이 무슨 일을하는지 간단하게해야 스트림으로 명명 된 파이프에 대한 액세스를 노출하는 .NET 프레임 워크에 NamedPipeClientStream/NamedPipeServerStream 클래스가있다.

데이터를 전달하는 간단한 해결책은 라인 기반 프로토콜을 사용하는 것입니다. 한 줄 = 매개 변수가있는 명령 한 개 :

using (NamedPipeClientStream pipeClient = 
     new NamedPipeClientStream(".", "testpipe", PipeDirection.In)) 
{ 
    pipeClient.Connect(); 

    using (StreamReader sr = new StreamReader(pipeClient)) 
    { 
     string command; 
     while ((command = sr.ReadLine()) != null) 
     { 
      Console.WriteLine("Received command: {0}", command); 
     } 
    } 
} 
+0

이것은 .NET 3.5 (System.Pipes)에서만 지원됩니다. 이전 버전의 P/Invoke에서 2.0을 사용하고 있습니다 ... 또한 old-school C++에서 보낸 사람을 기억합니다. – Shaitan00

+0

그런 다음'hPipeInst'를'System .IO.Stream'을 사용하면 거의 동일한 이점을 얻을 수 있습니다 (예 : 모든 OverlappedPtr 항목을 사용자에게 제공). 그리고 송신자 측에서는 파이프에 줄 바꿈 종료 문자열을 작성하고 반드시 구조체 일 필요는 없습니다. – dtb

+0

그리고 COMMAND와 PARAMETER 사이에 구분 기호를 사용 하시겠습니까? 두 부분을 모두 추출 할 수 있어야합니다 (매개 변수를 사용하여 수행 할 작업을 파악하기 위해 명령을 전환 할 때). – Shaitan00

관련 문제