2013-07-10 3 views
2

이 주제는 여기에서 많이 논의되지만 아무런 대답도 정확하지 않습니다. nettcpbinding으로 만든 wcf 서비스가 있습니다. 서버와 클라이언트간에 전송되는 메시지 크기/전송 된 데이터 속도/수신 된 데이터 속도를 검사하고 싶습니다. 서비스는 이중 채널이며 클라이언트 참조는 서비스 참조를 추가하여 자동 생성됩니다. 두 응용 프로그램 (클라이언트/서버)은 C# .Net 4.0으로 작성되었습니다.WCF tcp 바인딩 메시지 크기

<bindings> 
    <netTcpBinding> 
    <binding name="largeMessage" 
      receiveTimeout="infinite" 
      sendTimeout="24:00:00" 
      openTimeout="00:00:10" 
      closeTimeout="00:00:10" 
      maxReceivedMessageSize="2147483647" 
      maxBufferSize="2147483647" 
      maxConnections="2000" 
      transactionFlow="false" 
      listenBacklog="2147483647" 
      maxBufferPoolSize="2147483647"> 
     <readerQuotas maxDepth="128" 
      maxArrayLength="200000000" 
      maxStringContentLength="2147483647"/> 
     <security mode="None" /> 
     <reliableSession enabled="false" ordered="true" inactivityTimeout="infinite" /> 
    </binding> 
    </netTcpBinding> 
</bindings> 

서비스는 자체 호스팅 및 작성하여 콘솔 응용 프로그램으로 시작됩니다 :

ServiceHost host = new ServiceHost(serviceObject, addresses); 
다음과 같이 nettcp 기본 바이너리 인코더와 서버 측에서 구성 설정을 사용하고 있음을 바인딩입니다

나는 wireshark를 사용하여 일반 통계를 얻었고 전송 된 tcp 패킷은 매우 높은 데이터 전송률을가집니다. 그래서 클라이언트와 서버간에 전송되는 각 메시지 크기를 검사하고 싶습니다. 이 포럼에서 제안 된 메시지 크기를 측정하기 위해 몇 가지 기술을 사용했지만 wireshark와 동일한 크기는 제공하지 않았습니다. WCF - Measuring approximate message sizes programmatically

이 링크 : http://winterdom.com/2009/07/comparing-text-and-binary-serialization-in-wcf/

내 코드에서 이런 짓을 :

static byte[] SerializeToBin<T>(T obj) 
    { 
     Message msg = ObjectToMessage(obj); 
     MessageEncodingBindingElement mebe = new BinaryMessageEncodingBindingElement(); 
     mebe.MessageVersion = MessageVersion.Soap12; 
     return Serialize(msg, mebe.CreateMessageEncoderFactory()); 
    } 

    static byte[] Serialize(Message msg, MessageEncoderFactory factory) 
    { 
     MessageEncoder enc = factory.Encoder; 
     MemoryStream stream = new MemoryStream(); 
     enc.WriteMessage(msg, stream); 
     return stream.ToArray(); 
    } 

    static Message ObjectToMessage<T>(T obj) 
    { 
     DataContractSerializer ser = new DataContractSerializer(typeof(T)); 
     return Message.CreateMessage(MessageVersion.Soap12, "", obj, ser); 
    } 

는 정확한 결과를 제공하지 않습니다

은 이미 다음 테스트. 이것은 또한하지 않습니다

private void DetermineAndLogMessageDiagnostics(ref Message message, eMessageDirection messageDirection) 
    { 
     long sizeInBytes = 0; 
     var mb = message.CreateBufferedCopy(int.MaxValue); 
     message = mb.CreateMessage(); 

     var ms = new MemoryStream(); 
     using (var memWriter = XmlDictionaryWriter.CreateBinaryWriter(ms)) 
     { 
      mb.CreateMessage().WriteMessage(memWriter); 
      memWriter.Flush(); 
      sizeInBytes = ms.Position; 
     } 

     //Recalculates the updated average and updates the variables 
     //sentBytes, averageSentbps, receivedBytes, averageReceivedbps 
     RecalculateAverage(bodySizeInBytes, messageDirection); 
     Logger.Info("Message '{0}' size: {1} bits/{2} bytes. ({3} KBits). Sent (Total: {4} Bytes, {5:0.00} bps). Received (Total: {6} Bytes, {7:0.00} bps)", 
      action, 
      sizeInBytes * 8, 
      sizeInBytes, 
      ((double)sizeInBytes * 8)/1024, 
      sentBytes, 
      averageSentbps, 
      receivedBytes, 
      averageReceivedbps 
      ); 
    } 

:이 문서 http://devlicio.us/blogs/derik_whittaker/archive/2011/02/03/how-to-intercept-a-wcf-message-to-track-message-size.aspx 에서 제안하고이 함수 호출로 보내기/메시지 수신 -

그럼 내가 메시지 관리자를 추가하고 후 /를하기 전에 듣고 시도 정확한 결과를 제공하십시오. 내가 정확하지 않다고 말하면 - 약 300 - 500 바이트 차이를 의미합니다. 그러나 그 격차는 일정하지 않습니다.

netTcpBinding을 검사하고 구성을 변경하고 싶지 않기 때문에 사용자 지정 바인딩을 만들고 싶지 않았습니다.

누구에게이 문제에 대한 정확한 해결책이 있습니까?

이 긴 질문에 대한 설명을 읽어 주셔서 감사합니다.

그리고 제안 된 솔루션에 대해 미리 감사드립니다.

답변

1

메시지 크기를 정확하게 측정 할 수있는 유일한 방법은 사용자 지정 메시지 인코더를 사용하는 것입니다. 원래의 엔코더를 래핑 할 수 있으며 그 시점에서 (WriteMessageReadMessage에 대한 호출에서 메시지 크기를 볼 수 있습니다.)

이진 작성기를 사용하여 스트림에 메시지를 쓰면 정확한 결과를 얻을 수 없기 때문에 NetTcpBinding에 사용되는 이진 엔코더는 전송 중에 메시지를 압축하기 위해 dictionaries을 사용합니다.

+0

[http] //www.windowsazure.com에서 다운로드 할 수 있습니다.net/2008/08/15/calculated-wcf-message-size /) – sattias

+0

내가 말했듯이, 귀하의 질문에 귀하가 가지고있는 메시지를 덤핑하고 링크가 제안한대로 메시지를 압축 할 수있는 사전은 사용하지 않습니다 바이너리 형식 이를 위해서는 사용자 정의 인코더가 필요합니다. – carlosfigueira

+0

감사합니다. 내 CustomEncoder를 만들기 위해 CustomBinding을 작성해야한다는 것을 의미합니까? 만약 내가 CustomBinding을 만들려면 netTcpBinding과 같은 설정을 원한다. 이 작업을 수행 할 수 있습니까? – sattias