C++;套接字选项重用端口 我有一个C++套接字的问题。 我正在使用MFC的CAsyncSocket,我想加入一个多播组。 此外,我需要在这个组中有多个侦听器,这就是我遇到麻烦的地方。 我在网上找到了一些例子,但似乎不起作用。 这是我的密码: //create socket on port 17233 BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ); //set reuse socket option BOOL bMultipleApps = TRUE; bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); //join multicast group ip_mreq m_mrMReq; // Contains IP and interface of the host group m_mrMReq.imr_multiaddr.s_addr = inet_addr((LPCSTR)"224.30.0.1"); /* group addr */ m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */ int uRes =setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq));

C++;套接字选项重用端口 我有一个C++套接字的问题。 我正在使用MFC的CAsyncSocket,我想加入一个多播组。 此外,我需要在这个组中有多个侦听器,这就是我遇到麻烦的地方。 我在网上找到了一些例子,但似乎不起作用。 这是我的密码: //create socket on port 17233 BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ); //set reuse socket option BOOL bMultipleApps = TRUE; bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); //join multicast group ip_mreq m_mrMReq; // Contains IP and interface of the host group m_mrMReq.imr_multiaddr.s_addr = inet_addr((LPCSTR)"224.30.0.1"); /* group addr */ m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */ int uRes =setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq));,c++,sockets,multicast,C++,Sockets,Multicast,运行此操作时没有错误。 但当我尝试运行应用程序的另一个实例时,它无法在该端口上创建新的套接字,因为该端口正在使用中 我在C#中做过这件事,效果很好,如下所示: IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); s.Bind(ipep); IPAddress ip = IPAddre

运行此操作时没有错误。
但当我尝试运行应用程序的另一个实例时,它无法在该端口上创建新的套接字,因为该端口正在使用中

我在C#中做过这件事,效果很好,如下所示:

IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
s.Bind(ipep);
IPAddress ip = IPAddress.Parse(mcastGroup);
s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, IPAddress.Any));
s.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.MulticastTimeToLive, int.Parse("1"));
因此,如果有人发现我的代码有问题或有一些建议,我将非常感激

编辑1:
CAsyncSocket是TCP套接字吗

编辑2: 阅读后
我想我弄糊涂了。我需要一个多播UDP端口,可以由多个应用程序使用SO\ U REUSEADDR访问

编辑澄清:

BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ)
创建UDP套接字并绑定到端口17223。
对于
SetSockOpt(SO_REUSEADDR,(void*)和bMultipleApps,sizeof(BOOL),SOL_SOCKET)要工作,您需要在绑定之前设置它,正如@Hasturkun所说。
最终的工作代码如下所示:

    BOOL bRet = Socket(SOCK_DGRAM, FD_READ);
    if(bRet != TRUE)
    {
        UINT uErr = GetLastError();
        std::cout<<"Error:"<<uErr<<std::endl;
        return FALSE;
    }else{
        std::cout<<"Create sock: OK"<<std::endl;
    }

    //add reuse
    BOOL bMultipleApps = TRUE;      /* allow reuse of local port if needed */
    SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);

    //bind
    bRet = Bind(17233, NULL);
    if(bRet != TRUE)
    {
        UINT uErr = GetLastError();
        std::cout<<"Error(BIND):"<<uErr<<std::endl;
    }else{
        std::cout<<"BIND sock: OK"<<std::endl;
    }
BOOL bRet=Socket(SOCK_DGRAM,FD_READ);
if(bRet!=真)
{
UINT uErr=GetLastError();

我猜,这是因为您正在将客户端套接字绑定到特定的端口和地址。可能在其构造函数上:

BOOL-bRet=Create(17233,SOCK\u DGRAM,FD\u READ);

您不应将客户端套接字绑定到地址。让windows为您管理。您应该可以选择不创建通过特定端口的套接字,或者如果不创建,则应使用其他端口创建套接字

另外,
BOOL bMultipleApps=TRUE;
选项的工作方式与您想象的不一样。它在套接字中设置了一个延迟选项,但一旦创建并侦听,套接字(我指的是套接字端口)就无法在其他应用程序中使用,无论您做什么

看看这个:

编辑:

我也不知道c#code中的
port
值:

IPEndPoint ipep=新的IPEndPoint(IPAddress.Any,port);

您确定每次运行应用程序时,
端口
不会获得不同的值吗

正如我所说的,尝试在不同的端口中创建套接字,看看会发生什么。谷歌搜索
以便了解它的含义

编辑2:

看看:

编辑3:

也许你的c代码是:

正在将地址绑定到另一个NIC。同一台计算机上有两个NIC吗?如果有,可以在两个NIC中绑定相同的端口

编辑4:


使用UDP套接字的示例:

我猜,发生这种情况是因为您将客户端套接字绑定到特定的端口和地址。可能在其构造函数上:

BOOL-bRet=Create(17233,SOCK\u DGRAM,FD\u READ);

您不应将客户端套接字绑定到地址。让windows为您管理。您应该可以选择不创建通过特定端口的套接字,或者如果不创建,则应使用其他端口创建套接字

另外,
BOOL bMultipleApps=TRUE;
选项的工作方式与您想象的不一样。它在套接字中设置了一个延迟选项,但一旦创建并侦听,套接字(我指的是套接字端口)就无法在其他应用程序中使用,无论您做什么

看看这个:

编辑:

我也不知道c#code中的
port
值:

IPEndPoint ipep=新的IPEndPoint(IPAddress.Any,port);

您确定每次运行应用程序时,
端口
不会获得不同的值吗

正如我所说的,尝试在不同的端口中创建套接字,看看会发生什么。谷歌搜索
以便了解它的含义

编辑2:

看看:

编辑3:

也许你的c代码是:

正在将地址绑定到另一个NIC。同一台计算机上有两个NIC吗?如果有,可以在两个NIC中绑定相同的端口

编辑4:

使用UDP套接字的例子:

如果是一个选项,考虑使用ASIO。它非常直截了当,并且示例显示一个简单的多播接收器。

多个侦听器的重要部分是:

socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
如果您不清楚应用程序在做什么,只需运行
netstat
,您将看到套接字以及它们的绑定方式(IP、端口和协议):

查找您感兴趣的端口。如果您运行多个应用程序,监听同一个端口,您将看到同一个端口的多个条目,其中UDP作为协议。

< P>如果您是一个选项,请考虑使用ASIO。这是非常直接的,并且示例显示了一个简单的多播接收器。 多个侦听器的重要部分是:

socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
如果您不清楚应用程序在做什么,只需运行
netstat
,您将看到套接字以及它们的绑定方式(IP、端口和协议):


…并查找您感兴趣的端口。如果您运行多个应用程序侦听同一端口,您应该会看到使用UDP作为协议的同一端口的多个条目。

您应该能够将套接字的创建与绑定分离,使用创建套接字,例如

然后在设置sockopt后将其与绑定

BOOL bMultipleApps = TRUE;
bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);

bRet = Bind(17233, NULL);

您应该能够将套接字的创建与绑定分开,使用创建套接字,例如

然后在设置sockopt后将其与绑定

BOOL bMultipleApps = TRUE;
bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);

bRet = Bind(17233, NULL);

如果我不调用Create(绑定套接字),我就不能调用setsockopt。我没有说你不应该创建。我只是说你正在尝试在两个应用程序中使用相同的端口。这是不可能的。因此c#s.SetSocketOption(SocketOptionLevel.socket,SocketOptionName.ReuseAddress,
BOOL bMultipleApps = TRUE;
bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);

bRet = Bind(17233, NULL);