2011-03-14 3 views
1

나는 하루의 더 나은 부분을 위해 내 머리에 맞서 싸웠다. 기본적으로 소스 게임 엔진에는 RCON (원격 콘솔 오버 네트워크?)에 대한 문서화 된 프로토콜이 있습니다.이 프로토콜은 재현하려는 프로토콜입니다. 수백 가지 예제가 있지만 모두 클라이언트 측에서 (게임 서버의 RCON에 대한 연결을 설정하는) 어디에서 실제로 클라이언트에 응답 할 서버 부분을 다시 만들려고하는지 알 수 있습니다.C# TCP 서버 응답 패킷 문제

다음은 RCON 프로토콜에 대한 정보입니다. 내가 인증 요청을 받으면 모든 것이 정상입니다. 내가 회신을 시도하고 연결이 정상적으로 이루어지면 연결이 실패합니다. 그래서 답을 할 때 뭔가 잘못하고 있지만 확실하지 않습니다.

http://developer.valvesoftware.com/wiki/Source_RCON_Protocol

private void ReadClientPacket(object client) 
{ 
    TcpClient tcpClient = (TcpClient)client; 
    NetworkStream clientStream = tcpClient.GetStream(); 

    while (true) 
    { 
     try 
     { 
      int packetsize; 

      // Create a new Packet Object and fill out the data from the incoming TCP Packets 
      RCONPacket packet = new RCONPacket(); 

      using (BinaryReader reader = new BinaryReader(clientStream)) 
      { 
       // First Int32 is Packet Size 
       packetsize = reader.ReadInt32(); 

       packet.RequestId = reader.ReadInt32(); 
       packet.RconDataReceived = (RCONPacket.RCONDATA_rec)reader.ReadInt32(); 

       Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.RconDataReceived); 

       // Read first and second String in the Packet (UTF8 Null Terminated) 
       packet.String1 = ReadBytesString(reader); 
       packet.String2 = ReadBytesString(reader); 

       Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2); 

       switch (packet.RconDataReceived) 
       { 
        case RCONPacket.RCONDATA_rec.SERVERDATA_AUTH: 
        { 
         ReplyAuthRequest(packet.RequestId, tcpClient); 
         break; 
        } 
        case RCONPacket.RCONDATA_rec.SERVERDATA_EXECCOMMAND: 
        { 
         //ReplyExecCommand(packet.RequestId, tcpClient); 
         break; 
        } 
        default: 
        { 
         break; 
        } 
       } 
      } 

      break; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
      break; 
     } 
    } 

    tcpClient.Close(); 
} 

private void ReplyAuthRequest(int RequestID, TcpClient client) 
{ 
    Console.WriteLine("Replying to Auth Request"); 

    // Authentication Reply 
    using (NetworkStream clientStream = client.GetStream()) 
    using (MemoryStream stream = new MemoryStream()) 
    using (BinaryWriter writer = new BinaryWriter(stream)) 
    { 
     writer.Write((int)10); // Packet Size 
     writer.Write(RequestID); // Mirror RequestID if Authenticated, -1 if Failed 
     writer.Write((int)RCONPacket.RCONDATA_sent.SERVERDATA_AUTH_RESPONSE); 
     writer.Write(ConvertStringToByteArray("" + char.MinValue)); 
     writer.Write(ConvertStringToByteArray("" + char.MinValue)); 
     byte[] buffer = stream.ToArray(); 
     Console.WriteLine("size of full auth response packet is {0}", buffer.Length); 

     clientStream.Write(buffer, 0, buffer.Length); 
     clientStream.Flush(); 
    } 
} 

답변

0

은 당신이 Wireshark을 사용하고 있나요?

이 도구는 기존 프로토콜을 복사/역 엔지니어링하려고 할 때 필수적입니다. 알려진 클라이언트와 정상적인 인증을 수행하고 로그를 저장하십시오. 그런 다음 자신의 코드를 사용하여 와이어에서 전송 된 비트가 로그의 비트와 다른 위치를 확인하십시오. 는 '\ n을'같은 코드를보고 바로 볼 수

때때로 그것의 아주 어려운 일이 잘못된 지점에 삽입하기, 또는 전체 메시지 후 여분의 라인은

0

나는 비슷한 문제를 했어 귀하의 회신 기능에서 전

동안은 :

using (NetworkStream clientStream = client.GetStream()) 
(...) 

clientStream의 처리는 범인이 될 수 있습니다. 내 경우에는 스트림의 처리로 인해 연결 종료가 발생하고 GetStream()은 스트림의 새 인스턴스를 반환하지 않고 TCPClient가 소유 한 Stream을 반환합니다. 도움이되는지 확인하십시오.