|
本帖最后由 htttg 于 2021-5-25 15:54 编辑
在项目中需要用到多播mdns, 按照下面的方法初始化网络和设置收包处理函数。多次启动程序,有大概10%左右的几率收不到数据包(网卡已经收到了,用Wireshark可以看到),不知道是什么原因,希望各位高人指点,万分感谢。
BOOL InitSocket()
{
// Join MDNS group
m_socketMdns = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
if (m_socketMdns == INVALID_SOCKET)
{
MessageBox(_T("Create socket fail!"));
return 0;
}
// Set socket option to reuse the port
bFlag = TRUE;
iRet = 0;
iRet = setsockopt(m_socketMdns, SOL_SOCKET, SO_REUSEADDR, (char*)&bFlag, sizeof(bFlag));
if (iRet == SOCKET_ERROR)
{
closesocket(m_socketMdns);
MessageBox(_T("Set socket to reuse the port fail!"));
return 0;
}
// Bind the socket to local address
addrLocal.sin_family = AF_INET;
addrLocal.sin_port = htons(MDNS_PORT);
addrLocal.sin_addr.s_addr = localIP;
iRet = bind(m_socketMdns, (SOCKADDR*)&addrLocal, sizeof(SOCKADDR));
if (iRet == SOCKET_ERROR)
{
closesocket(m_socketMdns);
AfxMessageBox(_T("Bind socket error!"));
return 0;
}
// Set multicasting TTL option, 转发次数,本网内传播为1
TTL = 8;
iRet = setsockopt(m_socketMdns, IPPROTO_IP, IP_MULTICAST_TTL,
(const char*)&TTL, sizeof(int));
if (iRet == SOCKET_ERROR)
{
closesocket(m_socketMdns);
AfxMessageBox(_T("Set multicasting option error!"));
return FALSE;
}
SOCKADDR_IN m_addrRemote;
char m_strMdnsAddress[] = "224.0.0.251";// 多播地址
// Join multicast group
m_addrRemote.sin_family = AF_INET;
m_addrRemote.sin_port = htons(MDNS_PORT);
m_addrRemote.sin_addr.s_addr = inet_addr(m_strMdnsAddress);
m_multicastSocketMdns = WSAJoinLeaf(m_socketMdns, (SOCKADDR*)&m_addrRemote, sizeof(m_addrRemote),
NULL, NULL, NULL, NULL,
JL_BOTH);// Both of Sender and Receiver
if (m_multicastSocketMdns == INVALID_SOCKET)
{
closesocket(m_socketMdns);
str.Format(_T("Join multicast leaf error! Error Code:%u\n"), WSAGetLastError());
MessageBox(str);
return FALSE;
}
// Set callback routine
iRet = WSAAsyncSelect(m_socketMdns, m_hWnd, UM_MDNS, FD_READ);
if (iRet == SOCKET_ERROR)
{
MessageBox(_T("m_multicastSocketMdns select error!"));
closesocket(m_multicastSocketMdns);
closesocket(m_socketMdns);
return FALSE;
}
}
LRESULT CMainView::OnMdns(WPARAM wp, LPARAM lp)
{
CString str;
DWORD dwFlag(0);
DWORD dwRead(100);
BYTE buf[1500] = { 0 };
WSABUF wsabuf = { 1500,(char*)buf };
SOCKADDR_IN addrFrom;
int len = sizeof(SOCKADDR);
switch (LOWORD(lp))
{
case FD_READ:
if (SOCKET_ERROR == WSARecvFrom(m_socketMdns, &wsabuf, 1, &dwRead,
&dwFlag, (SOCKADDR*)&addrFrom, &len, NULL, NULL))
{
MessageBox(_T("No data!"));
return 0;
}
TRACE()
if (0 == buf[2] && buf[5])
{
TRACE(_T("MDNS query\r\n"));
}
else if (0x84 == buf[2] && buf[7])
{
TRACE(_T("MDNS response\r\n"));
}
}
return 0;
} |
上一篇: c++习题求解下一篇: C 库函数 - sscanf()
|