Windows 10应用程序C#tcp客户端

时间:2016-03-21 13:52:09

标签: c# win-universal-app

我创建了一个Arduino + windows 10应用。微控制器连接Wi-Fi模块(ESP8266-ESP01),tcp / ip协议。模块是服务器,app是客户端。该模块工作正常,我在另一个程序(“SocketTest v3.0”)上测试它。它发送和接收数据。但是我的app只能写数据,socket.InputStream不起作用。当我读取数据时,它会抛出错误。

我做错了什么?

也许有一个像这个程序的例子:

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";
        }
    }
}

也许我的阅读功能不太好,但错误是在每种情况下

dataReader.UnconsumedBufferLength == 0;

当我使用时:

int length = dataReader.ReadInt32();

它会引发异常。

1 个答案:

答案 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));