2008-09-18 4 views
7

Java로 작성된 서버에 C# 클라이언트를 작성하려고합니다. 서버는 4 바이트 (Java에서 DataInputStread readInt()) 메시지 헤더와 실제 메시지를 기다립니다.C# 클라이언트에서 Java 서버로 4 바이트 메시지 헤더 보내기

C#을 처음 접했을 때 어떻게해야이 메시지 헤더를 Java Server로 보낼 수 있습니까? 나는 그것을 여러 가지 방법으로 시도했다. (대부분 C# 언어를 너무 깊이 사용하지 않고 시행 착오를 시도했다.) 아무 것도 효과가 없었다. 자바 쪽은 잘못된 (매우 큰) 메시지 길이로 끝났다.

답변

2

간단하지만 엔디안을 확인 했습니까? 그것은 쉽게 당신의 데이터를 전송 한 엔디안과 당신이 잡된다 엔디안 사이에 불일치가 될 수

0

나는 C# .NET을 잘 모릅니다하지만 당신은 그냥이의 상당 수행해야합니다.

out.write((len >>> 24) & 0xFF); 
out.write((len >>> 16) & 0xFF); 
out.write((len >>> 8) & 0xFF); 
out.write((len >>> 0) & 0xFF); 
1

하는 경우를 당신은 많은 양의 데이터를 교환 할 것이고, 네트워크 순서로 int를 쓰고 읽을 수있는 Stream-wrapper를 구현 (또는 찾음)하는 것이 좋습니다. 다른 포스터는 지적으로 엔디 언 아래로,

using(Socket socket = ...){ 
    NetworkStream ns = new NetworkStream(socket);  
    ns.WriteByte((size>>24) & 0xFF); 
    ns.WriteByte((size>>16) & 0xFF); 
    ns.WriteByte((size>>8) & 0xFF); 
    ns.WriteByte(size  & 0xFF); 
    // write the actual message 
} 
11

그것은이다 :하지만 당신은 정말로 유일한 길이를 작성해야하는 경우 같은 것을 할.

Java DataInputStream은 데이터가 big-endian (네트워크 바이트 순서) 일 것으로 예상합니다. Mono 문서 (BinaryWriter과 같은 항목)에서 볼 때 C#은 리틀 엔디안 (Win32/x86에서는 기본값)으로 사용됩니다.

는 32 비트 INT '1'바이트를 변경하려면 표준 클래스 라이브러리를 사용할 때

그래서, 그들은 다른 결과 생산 :

: 당신은 C#에서의 int를 작성하는 방법을 변경할 수 있습니다

//byte hex values 
Java: 00 00 00 01 
    C#: 01 00 00 00 

private static void WriteInt(Stream stream, int n) { 
    for(int i=3; i>=0; i--) 
    { 
     int shift = i * 8; //bits to shift 
     byte b = (byte) (n >> shift); 
     stream.WriteByte(b); 
    } 
} 

편집 :

이 일의 안전한 방법은 다음과 같습니다

private static void WriteToNetwork(System.IO.BinaryWriter stream, int n) { 
    n = System.Net.IPAddress.HostToNetworkOrder(n); 
    stream.Write(n); 
} 
2

모두가 이미 지적했듯이이 문제는 C# 응용 프로그램이 리틀 엔디안 순서로 int를 보내는 것과 Java 응용 프로그램에서 int를 네트워크 순서 (big-endian)로 예상하기 때문에 발생했을 가능성이 큽니다. 그러나 C# 응용 프로그램에서 바이트를 명시 적으로 다시 배열하는 대신 올바른 방법은 호스트에서 네트워크 순서 (htons 등)로 변환하기위한 내장 함수에 의존하는 것입니다.이 방법을 사용하면 코드를 실행해도 잘 작동합니다. 빅 엔디 언 머신에서.

일반적으로 이러한 문제를 해결할 때 netcat 또는 wireshark와 같은 도구를 사용하여 올바른 트래픽 (예 : Java에서 Java로)을 기록한 다음 잘못된 트래픽과 비교하여 트래픽이 어디에 있는지 확인하는 것이 유용하다는 것을 알았습니다 잘못되어가는. 추가 이득으로 netcat을 사용하여 캡쳐/사전 기록 된 요청을 서버에 주입하거나 캡처/미리 녹음 된 응답을 클라이언트에 주입 할 수 있습니다. 또한 파일에서 요청/응답을 수정하고 코드를 수정하기 전에 결과를 테스트 할 수 있습니다.

0

Sysetm.Net.IPAddress 클래스에는 변환을 수행하는 HostToNetworkOrder() 및 NetworkToHostOrder()의 두 가지 정적 도우미 메서드가 있습니다. 스트림을 통해 BinaryWriter와 함께 사용하여 적절한 값을 쓸 수 있습니다.

using (Socket socket = new Socket()) 
using (NetworkStream stream = new NetworkStream(socket)) 
using (BinaryWriter writer = new BinaryWriter(stream)) 
{ 
    int myValue = 42; 
    writer.Write(IPAddress.HostToNetworkOrder(myValue)); 
} 
관련 문제