我创建了一个Arduino + windows 10
应用。微控制器连接Wi-Fi模块(ESP8266-ESP01),tcp / ip协议。模块是服务器,app是客户端。该模块工作正常,我在另一个程序(“SocketTest v3.0”)上测试它。它发送和接收数据。但是我的app只能写数据,socket.InputStream不起作用。当我读取数据时,它会抛出错误。
我做错了什么?
也许有一个像这个程序的例子:
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";
}
}
}
也许我的阅读功能不太好,但错误是在每种情况下
dataReader.UnconsumedBufferLength == 0;
当我使用时:
int length = dataReader.ReadInt32();
它会引发异常。
答案 0 :(得分:0)
第一个错误是dataReader.UnconsumedBufferLength == 0.并且函数.LoadAsync(...)抛出错误。
DataReader.UnconsumedBufferLength用于获取尚未读取的缓冲区的大小。在您调用s = dataReader.ReadString(length);
之前,尚未从输入流加载任何数据到中间缓冲区,因此值为0.并且参数为{{ 3}}不能为零,所以你得到一个System.ArgumentException:参数不正确。
如果我发送一个字符串“qwerty”并执行dataReader.LoadAsync(6)它会抛出 - > “该操作试图访问有效范围之外的数据”
代码await dataReader.LoadAsync(length);
抛出此异常,您需要调用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";
}
}
将字符串数据加载到缓冲区中,然后才能读取它。
以下是我验证过的示例代码:
int divider = graphGuide.indexOf(" ");
int NodeNum = Integer.parseInt(graphGuide.substring(0, divider));
int EdgeNum = Integer.parseInt(graphGuide.substring(divider + 1));