我的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?后 我觉得我很困惑。我需要一个多播UDP端口,可以使用SO_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;
}
谢谢,
加布里埃尔
答案 0 :(得分:1)
我想这是因为您将客户端套接字绑定到特定端口和地址。也许在它的构造函数上:
BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ);
您不应将客户端套接字绑定到地址。让windows为您管理。您应该可以选择不创建通过特定端口的套接字,或者如果不这样做,则应该使用另一个端口创建套接字。
此外,BOOL bMultipleApps = TRUE;
选项不会像您认为的那样工作。它在套接字中设置了一个逗留选项,但是一旦创建和监听,套接字(我的意思是套接字端口)就无法在其他应用程序中使用,无论你做什么。
检查出来:so-linger-and-closing-socketswinsock
修改强>
我也不知道你的c#代码中port
的值:
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
您确定每次运行应用时port
都没有获得不同的值吗?
正如我所说,尝试在不同的端口创建套接字以查看发生的情况。 Google so_linger
知道这意味着什么。
编辑2:
看看:Can two application listen to the same port?
编辑3:
也许你的c#代码:
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
将地址绑定到其他NIC。你在同一台电脑上有2个nic吗?如果这样做,您可以在两个端口绑定相同的端口。
编辑4:
使用UDP套接字的示例:Sending & Receiving UDP Datagrams with MFC's CAsyncSocket
答案 1 :(得分:1)
如果boost是您的选项,请考虑使用Asio。它非常简单,this示例显示了一个简单的多播接收器。
多个听众的重要部分是:
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
如果你不清楚你的应用程序在做什么,只需运行netstat
,你会看到例如套接字及其绑定方式(IP,端口和协议):
netstat -an
...并查找您感兴趣的端口。如果您运行多个应用程序侦听同一端口,您应该会看到同一端口的多个条目,其中UDP作为协议。
答案 2 :(得分:1)