C++ 套接字选项重用端口

标签 c++ sockets multicast

我有一个 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# 中完成了这个并且它像这样工作得很好:

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: 看完Can two applications listen to the same port?
我想我弄糊涂了。我需要一个可以被多个应用程序使用 SO_REUSEADDR 访问的多播 UDP 端口

编辑澄清:

BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ)

创建一个 UDP 套接字并绑定(bind)到端口 17223。
要使 SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); 正常工作,您需要在绑定(bind)之前设置它,如@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;
    }

谢谢,
加布里埃尔

;

最佳答案

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

BOOL bRet = Socket(SOCK_DGRAM, FD_READ);

然后用Bind绑定(bind)设置sockopt后

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

bRet = Bind(17233, NULL);

关于C++ 套接字选项重用端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5635086/

相关文章:

c# - 网络套接字-仅第一条消息总是会完成

java - 监听多播UDP地址

sockets - 监听对 UDP 多播消息的 UDP 单播回复

c++ - Ubuntu C++ 多播双留组消息

c++ - 在Qt窗口中嵌入skia控件

linux - 如果 TCP 服务器脱离网络,接受函数是否返回错误 (-1)

c++ - 具有接受派生类参数的基类参数的成员函数指针

sockets - Node.js 未捕获套接字异常 - 套接字已关闭

参数列表中带有省略号的 C++ Lambda

c++ - 在 C++ 应用程序中打开 Windows 中的 WPF 应用程序