2016-03-21 11 views
0

Ich habe eine Arduino + windows 10 App erstellt. Der Mikrocontroller wird mit einem Wi-Fi-Modul (ESP8266-ESP01), tcp/ip-Protokoll, verbunden. Das Modul ist der Server und die App ist der Client. Das Modul funktioniert einwandfrei und ich habe es in einem anderen Programm getestet ("SocketTest v3.0"). Es sendet und empfängt Daten. Aber meine App kann nur Daten schreiben, der Socket.InputStream funktioniert nicht. Wenn ich Daten lese, wird ein Fehler ausgegeben.Windows 10 App C# tcp Client

Was mache ich falsch?

Vielleicht gibt es ein Beispiel, wie dieses Programm:

image.

public sealed partial class MainPage : Page 
{ 
    StreamSocket _socket; 
    HostName _hostName; 
    DataWriter writer; 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     _socket = new StreamSocket(); 
    } 
    private async void connectButton_Click(object sender, RoutedEventArgs e) 
    { 

     #region _check_parameters 
     if (String.IsNullOrEmpty(hostName_Box.Text)) 
     { 
      _statusBar.Text += "[ERROR] Set the Host Name !!!\n"; 
      return; 
     } 
     if (String.IsNullOrEmpty(serviceName_Box.Text)) 
     { 
      _statusBar.Text += "[ERROR] Set the Service Name !!!\n"; 
      return; 
     } 
     try 
     { 
      _hostName = new HostName(hostName_Box.Text); 
     } 
     catch (Exception) 
     { 
      _statusBar.Text += "[ERROR] Invalid Host Name !!!\n"; 
      return; 
     } 
     #endregion 
     // If necessary, tweak the socket's control options before carrying out the connect operation. 
     // Refer to the StreamSocketControl class' MSDN documentation for the full list of control options. 
     _socket.Control.KeepAlive = false; 
     try 
     { 
      _statusBar.Text += "Connecting...\n"; 
      await _socket.ConnectAsync(_hostName, serviceName_Box.Text); 
      _statusBar.Text += "Connected\n"; 

      // go to send mode 
      connectButton.Content = "Send"; 
      connectButton.Click -= connectButton_Click; 
      connectButton.Click += send_Data; 
      hostName_Box.PlaceholderText = "data to send"; 
      hostName_Box.Text = ""; 
      writer = new DataWriter(_socket.OutputStream); 
     } 
     catch(Exception exception) 
     { 
      // If this is an unknown status it means that the error is fatal and retry will likely fail. 
      if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) 
      { 
       throw; 
      } 
      _statusBar.Text += "[ERROR] Connect failed with error:\n" + exception.Message + "\n"; 
     } 
    } 
    private async void read_data() 
    { 
     DataReader dataReader = new DataReader(_socket.InputStream); 
     dataReader.InputStreamOptions = InputStreamOptions.Partial; 
     try 
     { 
      await dataReader.LoadAsync(dataReader.UnconsumedBufferLength); 
      string s; 
      uint length; 
      length = dataReader.ReadUInt32(); 
      s = dataReader.ReadString(length); 
      _statusBar.Text += "Read successful\n" + s + "\n"; 
     } 
     catch (Exception exception) 
     { 
      _statusBar.Text += "[ERROR] Fail to load dada !!!\n" + 
       exception.Message + "\n"; 
     } 
    } 

    private async void send_Data(object sender, RoutedEventArgs e) 
    { 
     if (String.IsNullOrEmpty(hostName_Box.Text)) 
     { 
      _statusBar.Text += "Write anything\n"; 
      return; 
     } 
     if(hostName_Box.Text == "read") 
     { 
      try 
      { 
       hostName_Box.Text = ""; 
       read_data(); 
       return; 
      } 
      catch (Exception ex) 
      { 
       _statusBar.Text += "[ERROR] Reading data failed:\n" + ex.Message + "\n"; 
      } 
     } 
     writer.WriteUInt32(writer.MeasureString(hostName_Box.Text)); 
     writer.WriteString(hostName_Box.Text); 
     try 
     { 
      await writer.StoreAsync(); 
      _statusBar.Text += "\"" + hostName_Box.Text + "\" sent successfully\n"; 
      hostName_Box.Text = ""; 
     } 
     catch(Exception ex) 
     { 
      if (SocketError.GetStatus(ex.HResult) == SocketErrorStatus.Unknown) 
      { 
       throw; 
      } 
      _statusBar.Text += "[ERROR] Send failed with error:\n" + ex.Message + "\n"; 
     } 
    } 
} 

Vielleicht ist meine Lesefunktion nicht so gut, aber der Fehler ist, dass

in jeder Situation
dataReader.UnconsumedBufferLength == 0; 

und wenn ich benutze:

int length = dataReader.ReadInt32(); 

es eine Ausnahme auslöst.

+0

Bitte notieren Sie die Fehler/Ausnahmen Sie erhalten. –

+0

Der erste Fehler ist, dass die DataReader.UnconsumedBufferLength == 0. Und die Funktion .LoadAsync (...) wirft den Fehler. Wenn ich eine Zeichenfolge "QWERTY" sende und dataReader.LoadAsync (6) mache, gibt es -> "Der Vorgang versucht, auf Daten außerhalb des gültigen Bereichs zuzugreifen" –

+0

Gibt es eine Firewall auf dem Client, die Probleme verursachen könnte? –

Antwort

0

Der erste Fehler ist, dass die DataReader.UnconsumedBufferLength == 0. Und die Funktion. LoadAsync (...) wirft den Fehler.

DataReader.UnconsumedBufferLength verwendet die Größe des Puffer zu erhalten, die nicht gelesen wurde. Sie haben keine Daten aus dem Eingangsstrom auf den Zwischenpuffer geladen, bevor Sie dataReader.UnconsumedBufferLength aufgerufen, so ist der Wert 0. Und der Parameter DataReader.LoadAsync kann nicht Null sein, also haben Sie eine System.ArgumentException: Der Parameter ist falsch.

Wenn ich eine Zeichenfolge „qwertz“ senden und tun dataReader.LoadAsync (6) wirft -> „Die Betriebsdaten versucht außerhalb des zulässigen Bereichs acces“

Diese Ausnahme von geworfen wird Der Code s = dataReader.ReadString(length);, Sie müssen await dataReader.LoadAsync(length); aufrufen, um die Zeichenfolgedaten in den Puffer zu laden, bevor Sie es lesen können.

Es folgt der Beispielcode ich überprüft haben:

private async void read_data() 
{ 
    DataReader dataReader = new DataReader(_socket.InputStream); 
    dataReader.InputStreamOptions = InputStreamOptions.Partial; 
    try 
    { 
     //load some data to the buffer first 
     await dataReader.LoadAsync(4); 
     //read int data 
     uint length = dataReader.ReadUInt32(); 
     //load data to the buffer before reading it. 
     uint acturalStringLength = await dataReader.LoadAsync(length); 
     //read string data 
     string s = dataReader.ReadString(acturalStringLength); 
     _statusBar.Text += "Read successful\n" + s + "\n"; 
    } 
    catch (Exception exception) 
    { 
     _statusBar.Text += "[ERROR] Fail to load dada !!!\n" + 
      exception.Message + "\n"; 
    } 
}