runtime: Socket.Select() method doesn't work correctly in linux.
I use linux mint mate 17.2 which is ubuntu and debian based. I cannot connect to Ngpsql database from Linux client. But I can connect from Windows client.
Because: After the following line is called =>Socket.Select(null, write, error, perIpTimeout);
In Linux: The list write doesn’t have any elements. As a result it enters the if (!write.Any()) block and creates “Timeout exception” there.
In Windows: The list write has the element. It works.
Here is a sample code to produce it. It is a console application that works on CoreClr.
// Program.cs
using System;
// using Npgsql;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Linq;
namespace Sample
{
public class Program
{
public void Main()
{
Console.WriteLine("App started..");
string Host = "192.168.1.72";
int Port = 5432;
int perIpTimeout = -1;
var ips = Dns.GetHostAddressesAsync(Host).Result;
var ep = new IPEndPoint(ips[0], Port);
var socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
{
Blocking = false
};
try
{
try
{
socket.Connect(ep);
}
catch (SocketException e)
{
if (e.SocketErrorCode != SocketError.WouldBlock)
{
throw;
}
}
var write = new List<Socket> { socket };
var error = new List<Socket> { socket };
Socket.Select(null, write, error, perIpTimeout);
var errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
if (errorCode != 0)
{
throw new SocketException((int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error));
}
if (!write.Any())
{
// When it is Linux, it will enter this block here!
Console.WriteLine(
$"Timeout after {new TimeSpan(perIpTimeout * 10).TotalSeconds} seconds when connecting to {ips[0]}");
try { socket.Dispose(); }
catch
{
// ignored
}
// if i == 0
Console.WriteLine("i==0 exception");
throw new TimeoutException();
// continue;
}
socket.Blocking = true;
return;
}
catch (TimeoutException) { throw; }
catch
{
try { socket.Dispose(); }
catch
{
// ignored
}
Console.WriteLine("Failed to connect to " + ips[0]);
// if (i == 0)
Console.WriteLine("i==0 exception 2");
throw;
}
}
}
// TODO: Remove. Will be fixed in the next release of EF.
public class Startup
{
public void Configure() { }
}
}
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 35 (8 by maintainers)
In case anyone comes here and is having trouble with this, I’ve built a new System.Native.so which you may find helpful. It’s built from the tree as of rc1-update1, so it should be compatible with the rest of that release, but it also includes this one patch. You can download it from http://tmp.chown.org.uk/System.Native.so and you should install it in ~/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update1/bin .
I’m running 64bit Ubuntu Trusty. If you have a different system I doubt this file will work, and you’ll probably have to build it yourself.
With this fix, the Postgres driver and EntityFramework7.Npgsql work as expected, which is great news.
@Khumana this bug was fixed ages ago, so your problem is almost certainly something else. EF Core code first certainly works on Linux with Postgres, I’m using that exact configuration for a current project.
As you’re getting a timeout, perhaps check you’ve got the right host in your connection string, and make sure nothing is getting in the way of your network access to that host.
These are quite good news. Postgresql is the only db that has provider for ef and which works under linux. This makes the fix very important for me and probably for others. Many thanks and kind regards!