I`m trying to see what is wrong with my code for a tcp connection to a server in xamarin forms using the mvvm architecture. The client is connecting but when using streamReader.readLine() i get the following error:
System.IO.IOException: Unable to read data from the transport connection: Operation on non-blocking socket would block.
I´m using xamarin forms and System.Net.Sockets for the TcpClient instance. I´m trying synchronous communication for testing with the server.
I Have a TcpServer program proven to work with other devices. Below is some code to do the communication
The ViewModel of the connection properties page has the following code:
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 is an instance of TCPService, which has the Initialize function to establish connection and the sendMessage function where the error appears to be:
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;
}
}
I would be expecting to read the data in the ReadLine function. Also, I had some printing on the console on the server side if it recieves data and i'm seeing it is not.
Could somebody help me on where could I be wrong? A proven solution is also fine!
Thank you so much!
Whenever you use StreamWriter you need to Flush() the contents of the stream. I'll quote MSDN as the reason becomes quite clear:
Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.
You can use it like this:
var writer = new StreamWriter(client.GetStream());
writer.AutoFlush = true;
writer.WriteLine(eth.Message);
writer.Flush();
And there is a simple demo you can check: https://thuru.net/2012/01/07/simple-clientserver-in-c/