2017-08-04 4 views
1

Ich habe ein Programm, das einen TCPClient und Netzwerk-Stream verwendet, um Nachrichten von einer externen IP zu empfangen. Nachrichten werden ständig gesendet und das Programm übersetzt diese Nachrichten in ein für den Benutzer lesbareres Format.Schreib- und Lesezugriff auf Netzwerk-Stream zur gleichen Zeit C#

Die IP muss jedoch alle 8 Sekunden eine Keep Alive-Nachricht erhalten, um die Verbindung offen zu halten.

Ich habe Probleme mit dem Lesen von Nachrichten und Schreiben in den Stream zur gleichen Zeit. Ich hatte den Eindruck, dass man in einem Stream lesen und schreiben konnte, solange sie auf verschiedenen Threads waren.

Sobald der Timer abgelaufen ist und die Methode zum Schreiben der Keep Alive-Nachricht aufgerufen wird, erhalte ich den Fehler: Daten können nicht von der Transportverbindung gelesen werden: Eine hergestellte Verbindung wurde von der Software in Ihrem Hostcomputer abgebrochen. Dieser Fehler tritt auf, wenn versucht wird, ein Byte einzulesen, nachdem die Methode zum Schreiben in Datenstrom aufgerufen wurde.

Unten ist mein Code. Dies ist der Haupt:

public MainWindow() 
    { 
     InitializeComponent(); 

     client.Connect(address, port); 
     nwStream = client.GetStream(); 

     System.Timers.Timer newTimer = new System.Timers.Timer(8000); 
     newTimer.Elapsed += delegate { KeepAlive(nwStream, newTimer); }; 
     newTimer.Start(); 
     Thread t = new Thread(ReadInandOutputToTextBoxIfInvoke); 
     t.Start(); 
    } 

hier der Faden und ein Verfahren ist, das aus dem Strom lautet:

private void ReadInandOutputToTextBoxIfInvoke() 
    { 

     while (run) 
     { 
      string message = ""; 
      int x = 0; 
      int start = 35; 
      int messageLength; 
      int numberOfMessages; 

      // NetworkStream nwStream = client.GetStream(); 
      try 
      { 
       while ((x = nwStream.ReadByte()) != start) { if (x == -1) { continue; } } //if it doesnt begin with # or has gone over then break 

       //reads in message header which is length then number of messages 
       messageLength = nwStream.ReadByte(); 
       numberOfMessages = nwStream.ReadByte(); 

       string messageRecieved = new string(readMessage(nwStream, messageLength - 1)); 
       string[] messages = messageRecieved.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); 


       for (int i = 0; i < numberOfMessages; i++) 
       { 
        string messageToProcess = messages[i]; 
        char messageType = messageToProcess[0]; 

I ein Stück dieses Verfahrens entfernt, die die Nachricht übersetzt, da es nicht relevent wird.

Dies ist der Code, der aufgerufen wird, wenn der Timer abgelaufen ist:

private void KeepAlive(NetworkStream Ns, System.Timers.Timer MyTimer) 
    { 
     byte[] toSend = new byte[] { 35, 51, 49, 42, 124 }; 
     try 
     { 
      for (int i = 0; i < toSend.Length; i++) 
      { 
       Ns.WriteByte(toSend[i]); 
       Ns.Flush(); 
      } 
     } 
     catch 
     { 
      MyTimer.Close(); 
     } 
    } 
+1

Ich bin verwirrt, warum Sie alle 8 Sekunden eine Nachricht senden müssen, um die Verbindung lebendig zu halten, ist das etwas auf der anderen Seite, die alle 8 Sekunden hört? – Jaxi

+1

@Jaxi das Gerät, mit dem ich spreche, schließt die Verbindung, wenn es innerhalb einer bestimmten Zeit keine Keep Alive-Nachricht empfängt –

+0

Könnte ein Lock vielleicht helfen? –

Antwort

1

ich jetzt mein Problem gelöst haben. Es gab zwei Faktoren, die verhinderten, dass das Programm ordnungsgemäß funktionierte.

  1. Der Fehler wurde nicht mehr angezeigt, nachdem ich eine Sperre verwendet hatte.
  2. Die Nachricht wurde ich an das Gerät zu senden war im richtigen Format nicht - es in hex

Es ist nun perfekt funktioniert sein mußte. Danke an alle, die versucht haben zu helfen.

Verwandte Themen