Как правильно установить TCP-соединение на стороне клиента с сервером в формах xamarin? - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь выяснить, что не так с моим кодом для tcp-соединения с сервером в формах xamarin с использованием архитектуры mvvm.Клиент подключается, но при использовании streamReader.readLine () я получаю следующую ошибку:

System.IO.IOException: невозможно прочитать данные из транспортного соединения: операция на неблокирующем сокете блокируется.

Я использую формы xamarin и System.Net.Sockets для экземпляра TcpClient.Я пытаюсь установить синхронную связь для тестирования с сервером.

У меня есть программа TcpServer, которая работает с другими устройствами.Ниже приведен некоторый код для связи

ViewModel страницы свойств соединения имеет следующий код:

     public ICommand TestConnectionCommand { get { return new 
    RelayCommand(sendMsg); } }
    public ICommand ConnectCommand { get; set; }

    public void sendMsg()
    {
        this.Response = new Response();
        this.EthernetConn.Port = 9091;
        this.EthernetConn.Ip = SelectedDevice.Ip;

        if (String.IsNullOrEmpty(EthernetConn.Ip))
        {
            Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.IpValidation, Languages.Accept);
            return;
        }

        if (String.IsNullOrEmpty(EthernetConn.Timeout))
        {
            Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.TimeoutValidation, Languages.Accept);
            return;
        }

        this.EthernetConn.Message = "TESTING\n";
        tcpService.Initialize(this.ethernetConn);
        this.Response.Message = tcpService.sendMessage(this.EthernetConn);

        if (this.Response.Message.Contains("FormatException"))
        {
            this.Response.IsSuccess = false;
            Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.FormatValidation, Languages.Accept);
            this.IsRunning = false;
            this.IsEnabled = true;
            return;

        }
        else if (this.Response.Message.Contains("ArgumentNullException"))
        {
            this.Response.IsSuccess = false;
            Application.Current.MainPage.DisplayAlert(Languages.Error, this.Response.Message, Languages.Accept);
            this.IsRunning = false;
            this.IsEnabled = true;
            return;

        }
        else if (this.Response.Message.Contains("SocketException"))
        {
            this.Response.IsSuccess = false;
             Application.Current.MainPage.DisplayAlert(Languages.Error, this.Response.Message, Languages.Accept);
            this.IsRunning = false;
            this.IsEnabled = true;
            return;

        }
        else if (this.Response.Message.Contains("OK"))
        {
            this.Response.IsSuccess = true;
        }

        if (this.Response.IsSuccess)
        {
             Application.Current.MainPage.DisplayAlert(Languages.Success, Languages.ConnEstablished, Languages.Accept);
            this.IsRunning = false;
            this.IsEnabled = true;
        }
        else
        {
            Application.Current.MainPage.DisplayAlert(Languages.Error, Languages.ConnFailed, Languages.Accept);
            this.IsRunning = false;
            this.IsEnabled = true;
        }

    }

tcpService - это экземпляр TCPService, который имеет функцию Initialize для установления соединенияи функция sendMessage, где ошибка выглядит следующим образом:

    public void Initialize(EthernetConnection eth)
    {
        client.SendTimeout = Convert.ToInt16(eth.Timeout);
        client.ReceiveTimeout = Convert.ToInt16(eth.Timeout);
        client.Connect(eth.Ip, eth.Port);
    }


    public string sendMessage(EthernetConnection eth)
    {
        string response = String.Empty;
        try
        {
            if (!client.Connected)
            {
                return null;
            }
            var writer = new StreamWriter(client.GetStream());
            writer.WriteLine(eth.Message);

           //Here is where the problem seems to be:
            var reader = new StreamReader(client.GetStream());
            response = reader.ReadLine();

            return response;
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException: {0}", e);
            return "ArgumentNullException: " + e;
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
            return "SocketException:: " + e;
        }
        catch (FormatException e)
        {
            Console.WriteLine("SocketException: {0}", e);
            return "FormatException: " + e;
        }

        }

Я ожидал бы прочитать данные в функции ReadLine.Кроме того, у меня была некоторая печать на консоли на стороне сервера, если она получает данные, и я вижу, что это не так.

Может ли кто-нибудь помочь мне, в чем я могу ошибаться?Проверенное решение тоже подойдет!

Спасибо большое!

1 Ответ

0 голосов
/ 08 июня 2019

Каждый раз, когда вы используете StreamWriter, вам нужно Flush () содержимое потока. Я процитирую MSDN, поскольку причина становится совершенно ясной:

Очищает все буферы для текущего устройства записи и вызывает любые буферизованные данные. быть записанным в основной поток.

Вы можете использовать это так:

 var writer = new StreamWriter(client.GetStream());
 writer.AutoFlush = true;
 writer.WriteLine(eth.Message);
 writer.Flush();

И есть простая демонстрация, которую вы можете проверить: https://thuru.net/2012/01/07/simple-clientserver-in-c/

...