2014-11-18 8 views
0

IPEndpoint를 사용하여 TcpClient를 만들고 열린 연결로 NetworkStream을 엽니 다.BinaryFormatter는 스트림에서 여러 객체를 비 직렬화합니다.

stream = client.GetStream(); 

스트림은 하여 TcpClient는 NetworkStream 및 클라이언트로 정의된다. 스트림을 사용하여 매초 직렬화 된 객체를 보내려고합니다. 그렇게하려면 매분마다 BinaryFormatter을 통해 보내는 타이머가 있습니다.

formatter.Serialize(stream, object); 

이 경우 개체는 직렬화 된 클래스입니다. 다른 측면에서 나는 TcPListener 사용하고 의도 한대로 모든 작품 그 시점 전까지

stream = listener.AcceptTcpClient().GetStream(); 

로 스트림을 얻는다. 첫 번째 객체에는 원하는 정보가 있으며이 정보에도 액세스 할 수 있습니다. 동일한 스트림에서 두 번째 Object를 얻 자마자 NullReferenceException이 수신됩니다.

streamObject = deserialiser.Deserialize(stream); 

개체를 필터링하고 다른 방법을 시작할 수 있도록 특정 형식으로 deserialize하지 않습니다. * 송수신에는 두 개의 다른 클래스를 사용하며 두 클래스 모두 다른 프로그램에서 실행됩니다.

제 질문은 같은 스트림을 통해 여러 개의 스트림을 시간순으로 보내고 매 시간마다 스트림을 열고 닫지 않고 반대쪽으로 역 직렬화 할 수 있습니까?

* 일부 추가 정보 :

타이머가 스레드로 윈도우 서비스에서 실행됩니다. 첫 번째 객체는 위에서 언급 한 것처럼 전송되지만 두 번째 객체는 전송되지 않습니다.

내가받은 스택 추적은 다음과 같습니다.

System.NullReferenceException was not handled by user code. 
    HResult=-2147467261 
    Message=The Object reference not set to an object instance .. 
    Source=App_Web_qtieteli 
    StackTrace: 
     at _Default.Page_Load(Object sender, EventArgs e) in c:\Users\Documents\Visual Studio 2012\WebSites\System_GUI\Default.aspx.cs:Row 14. 
     at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) 
     at System.Web.UI.Control.OnLoad(EventArgs e) 
     at System.Web.UI.Control.LoadRecursive() 
     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
    InnerException: 

다음은 내 Page_Load 메소드입니다.

보호 된 무효 Page_Load (개체 보낸 사람, EventArgs 전자) { recive = new ServerRecive(); recive.ReciveStreamObject(); FirstDate.Text = recive.ui.serverName; }

수신을 정의하자 마자 연결이 열립니다. 그리고 여기 ServerRecive 클래스 전체에 대한 코드입니다.

public class ServerRecive 
{ 
public ObjectTypeUI ui {get; set;} 
public ObjectTypeSI si { get; set; } 
public ObjectTypeDI di { get; set; } 

TcpListener listener; 
NetworkStream stream; 

BinaryFormatter deserialiser; 

public ServerRecive() 
{ 
deserialiser = new BinaryFormatter(); 
Initialize(); 
} 

private void Initialize() 
{ 
listener = new TcpListener (IPAddress.Any, *port*); 
listener.Start(); 
stream = listener.AcceptTcpClient().GetStream(); 
} 


public void ReciveStreamObject() 
{ 
object Object = new object(); 
try 
{ 
    Object = deserialiser.Deserialize(stream); 
} 
catch (Exception e) {} 

if (Object.GetType() == typeof(ObjectTypeSI)) 
{ 
    si = (ObjectTypeSI)Object; 
} 
else if (Object.GetType() == typeof(ObjectTypeUI)) 
{ 
    ui = (ObjectTypeUI)Object; 
} 
else if(Object.GetType() == typeof(ObjectTypeDI)) 
{ 
    di = (ObjectTypeDI)Object; 
} 
} 
} 

다른 정보가 포함되어 있으므로 개체에 특정 크기가 없습니다.

@nelus 예외를 얻으려면 몇 가지 해결 방법을 사용했습니다. 이제 나는이 예외를 그래서 난 내 서버에도 데이터를 받아 봐 및 확인을 위해 로컬 호스트에 패킷 스니퍼를 사용하는 경우 테스트하는 두 번째 프로젝트를 구축했다

System.Runtime.Serialization.SerializationException was not handled. 
HResult=-2146233076 
Message=The input stream is not a valid binary format. The start content  
(in  Bytes) is: 1B-65-72-69-61-6C-4F-62-6A-65-63-74-2E-53-65-72-76 ... 
Source=mscorlib 
StackTrace: 
at 

System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser input) 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord() 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run() 
    at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) 
    at System_GUI.ServerRecive.ReciveStreamObject() in c:\Users\rbr\Documents\Visual Studio 2012\WebSites\System_GUI\App_Code\Netzwerk\ServerRecive.cs:Zeile 51. 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 
InnerException: 
+0

예외에 대한 세부 정보, 특히 스택 추적을 제공하면 도움이 될 것입니다. – neleus

+0

물론, 스택 추적은 실제 코드, 즉'Page_Load()'메소드 없이는 유용하지 않으며 정확히 어떤 객체 참조가 null인지를 명시하고 있습니다. –

+0

매번 연결을 다시 열거 나 열 었는가? 열린 채로있는 경우 - 개체 경계를 어떻게 식별합니까? – TGlatzer

답변

0

을 recived. 내가 암송에 사용하는 수업은 다른 것을하지 않았습니다. 스트림을 계속해서 비 직렬화하는 while 루프 만 있습니다. 이것은 내 문제를 해결했다.BinaryFormatter는 스트림의 객체를 찾고 객체의 실제 크기 나 위치를 모른 채 모든 객체를 deserialize하는 것처럼 보입니다.

class Program 
{ 
    TcpListener listener = new TcpListener(IPAddress.Any, 4456); 
    NetworkStream stream; 

    ObjectTypeUI ui; 
    ObjectTypeDI di; 
    ObjectTypeSI si; 

    BinaryFormatter deserializer = new BinaryFormatter(); 

    public Program() 
    { 

    listener.Start(); 
    stream = listener.AcceptTcpClient().GetStream(); 
    while (true) 
    { 
     object streamObject = deserializer.Deserialize(stream); 

     if (streamObject.GetType() == typeof(ObjectTypeSI)) 
     { 
      si = (ObjectTypeSI)streamObject; 
      Console.WriteLine(si.Kunde); 
     } 
     else if (streamObject.GetType() == typeof(ObjectTypeUI)) 
     { 
      ui = (ObjectTypeUI)streamObject; 
      Console.WriteLine(ui.CpuUsage); 
     } 
     else if(streamObject.GetType() == typeof(ObjectTypeDI)) 
     { 
      di = (ObjectTypeDI)streamObject; 
     } 
    } 


    } 

    static void Main(string[] args) 
    { 
    new Program(); 
    Console.ReadLine(); 
    } 
} 

실제 문제는 개체를 받아들이는 방식이나 역 직렬화하는 방식이 아닙니다. 문제는 실제로 내 개체를 보내는 데 사용하는 스레드를 중단 Windows 서비스입니다.

@neleus와 @ Grumbler85에게 큰 감사를 표하며 실제 문제를 찾는데 도움을주었습니다.

관련 문제