【问题标题】:C# IPv4/IPv6 agnostic socket listenerC# IPv4/IPv6 不可知的套接字侦听器
【发布时间】:2013-01-28 19:05:54
【问题描述】:

我试图弄清楚如何在 C# 中创建一个与协议无关的套接字侦听器——它应该获取 IPv4 和 IPv6 请求。我在 Google 上找到的所有内容似乎都是 C。尝试类似于我在 C 中看到的内容,我尝试了以下代码:

/*Socket*/ m_sock = null;
/*IPAddress*/ m_addr = null;
/*int*/ m_port = port; /*port passed to function*/
/*int*/ m_listenqueue = listen_queue_size; /*also passed to function, number of pending requests to allow before busy*/
IPAddress[] addrs = Dns.GetHostEntry("localhost").AddressList;
if(family == null) m_addr = addrs[0];
else
{
    foreach(IPAddress ia in addrs)
    {
        if(ia.AddressFamily == family) /*desired address family also passed as an argument*/
        {
            m_addr = ia;
            break;
        }
    }
}
if(m_addr == null) throw new Exception(this.GetType().ToString() + ".@CONSTRUCTOR@: Listener Initailization Error, couldn't get a host entry for 'localhost' with an address family of " + family.ToString());

m_sock = new Socket(m_addr.AddressFamily, SocketType.Stream, ProtocolType.IP);
/*START "AGNOSTICATION LOGIC"... Tried here...*/
if(m_addr.AddressFamily == AddressFamily.InterNetworkV6) //allow IP4 compatibility
{
    m_sock.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.AcceptConnection, true);
    /*fails*/ m_sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AcceptConnection, true);
    /*fails*/ m_sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AcceptConnection, true);
}
/*END "AGNOSTICATION LOGIC" */
IPEndPoint _endpoint = new IPEndPoint(m_addr, m_port);
m_sock.Bind(_endpoint);
/*... tried here*/
m_sock.Listen(m_listenqueue);
/*... and tried here*/

我已经尝试了标记的三个地方的逻辑,无论我放在哪里,列出的两行都会抛出一个无效参数异常。

谁能向我推荐我应该如何制作一个同时监听 IPv4/IPv6 的套接字?

【问题讨论】:

  • 修复InvalidArgumentException怎么样?
  • BindListen 方法应该足够了,根本不需要SetSocketOption
  • This blog post 可能有帮助吗?
  • @Anton Kovalenko - 这就是我的想法,但是当其他人尝试从 IPv4(如果侦听器是使用 InterNetworkV6 创建的)或 IPv6(如果侦听器是创建的)连接时,这会产生“连接被拒绝”错误使用互联网络)。
  • 源自 Sami 的评论 - 地址和套接字选项都需要 m_addr = IPAddress.IPv6Anym_sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);

标签: c# sockets ipv6 ipv4


【解决方案1】:

你可以使用 sock.SetSockOption(SocketOptionLevel.IPv6, SocketOptionName.IPV6Only, 0);将套接字设置为允许与 IPv6 以外的其他协议的连接。它将从 Vista 开始工作。

SocketOptionName documentation

【讨论】:

  • 工作,虽然我需要设置用于绑定套接字的地址IPAddress.IPv6Any
猜你喜欢
  • 2014-01-06
  • 2017-07-20
  • 1970-01-01
  • 2011-12-10
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
相关资源
最近更新 更多