2016-11-09 12 views
1

我的测试基础架构由3台机器组成:1台物理机器,运行hyperv的Windows 10和2台安装了ubuntu操作系统的虚拟机。所有机器之间都有完整的网络连接(它们互相ping通)。我编写了2个简单的C#程序:TCP客户端和TCP服务器(下面我附带了重现问题的最小代码)。当我在其中一台ubuntu机器上的windows计算机和服务器上运行客户端时,一切正常。然而,当我尝试在Ubuntu机和服务器的其他Ubuntu的机器上的一个运行客户端,然后我会在客户端的错误:不能连接到运行在Ubuntu上的单路IPv6 TCP服务器应用程序

TCPClientTest.exe信息:0:的System.Net.Sockets。 SocketException(0x80004005):在System.Net.Sockets的System.Net.Sockets.TcpClient.Connect(System.Net.IPAddress [] ipAddresses,System.Int32 port [0x000e9])中的[0x000e9] < 59be416de143456b88b9988284f43350>:0 无效参数 。 TcpClient.Connect(System.String hostname,System.Int32 port)[0x00007] in < 59be416de143456b88b9988284f43350>:0 at System.Net.Sockets.TcpClient..ctor(System.String hostname,System.Int32 port)[0x00006] in < 59be416de143456b88b9988 284f43350>:0 在TCPClientTest.Program.Main(System.String []参数)[0x00002]在:0 日期时间= 2016-11-09T21:25:42.4641950Z

TCP客户端:

TcpClient client = new TcpClient("fe80::3", 15000); 
NetworkStream stream = client.GetStream(); 
int number = stream.ReadByte(); 
stream.Close(); 
client.Close(); 

TCP服务器:

TcpListener server = new TcpListener(IPAddress.IPv6Any, 15000); 
server.Start(); 

TcpClient client = server.AcceptTcpClient(); 
NetworkStream stream = client.GetStream(); 
stream.WriteByte(199); 
stream.Close(); 
client.Close(); 

Ubuntu的版本:16.04 LTS

单声道版本:4.6服务版本0。 1(4.6.1.5)

可能是什么问题?

+0

C#不喜欢FE80 :: 3主机名称在Ubuntu出于某种原因 – Steve

+0

我已经把它改成:'TcpClient的客户端=新的TcpClient(AddressFamily.InterNetworkV6); client.Connect(IPAddress.Parse(“fe80 :: 3”),15000);'。问题是一样的。 –

+0

尝试IP V4并参见 – Steve

回答

0

我发现了这个问题。 IPv6链路本地地址与一个称为scope id的数字相关联,该数字指定了我们想要用于连接的网络接口。看起来在Linux系统中,我们必须明确地提供这些信息(即使使用ping6我们也需要这样做),但在Windows中没有这样的要求,根据这篇文章https://technet.microsoft.com/pl-pl/ms739166,它使用邻居发现并尝试为我们获得适当的接口。

例如: 在视窗ping fe80::3将工作正确的,但在Linux的,我们需要做的ping6 -I eth0 fe80::3ping6 fe80::3%2

TCP客户端必须稍微修改尊重ID范围,并指定其将要使用的网络接口正常工作:

IPAddress ipAddress = null; 

foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces()) 
{ 
    IPInterfaceProperties ipIntProperties = networkInterface.GetIPProperties(); 
    foreach (UnicastIPAddressInformation addr in ipIntProperties.UnicastAddresses) 
    { 
     String addressWithoutScopeId = addr.Address.ToString().Split('%')[0]; 
     if (addressWithoutScopeId.Equals("fe80::2")) 
     { 
      ipAddress = addr.Address; 
      break; 
     } 

    } 
    if (ipAddress != null) 
     break; 
} 

var endPoint = new IPEndPoint(ipAddress, 0); 
TcpClient client = new TcpClient(endPoint); 
client.Connect(IPAddress.Parse("fe80::3"), 15000); 
NetworkStream stream = client.GetStream(); 
int number = stream.ReadByte(); 
stream.Close(); 
client.Close(); 
+1

不保证在没有范围ID的情况下在Windows上正常工作。这是链接本地地址的必填字段。 –

相关问题