UDP组播,完成端口,双网卡收不到数据?各位大哥,帮帮忙?

MTomato 2011-05-17 03:45:42

各位大哥:

小弟我写了一个网络通信程序,通过完成端口在指定的网卡上接收网络上传输过来的语音数据,现在情况是:
1:各主机均配置了两张网卡,其中一张网卡由该程序使用,另一张网卡其他程序在用;
2:程序在大部分客户端上运行都正常,唯独在其中一个客户端上GetQueuedCompletionStatus该函数不返回,若该客户端把另一张网卡的网线拔掉,或者禁用掉该网卡,启动软件工作正常。在工作过程中插上另一张网卡的网线也没有问题。但是如果在程序启动前两张网卡都在工作,则GetQueuedCompletionStatus不返回。

主要代码如下:

调用Create函数的代码:
m_Receive.Create(uLocalPort,lpDstStr,0, lpBindAddr)

uLocalPort:组播端口
lpDstStr:组播地址
lpBindAddr:本机上要绑定的网卡地址

bool CUdpSocket::Create(USHORT uLocalPort,LPCTSTR lpDstAddr,USHORT uDstPort,LPCTSTR lpBindAddr/*=NULL*/)
{
if ( htons(uLocalPort) == m_stLclAddr.sin_port
&& m_stDstAddr.sin_addr.s_addr == inet_addr(lpDstAddr)
&& m_stDstAddr.sin_port == htons(uDstPort))
{
return true ;
}
//*/
if (!CreateSocket(uLocalPort,lpBindAddr))
return false ;
/* Assign our destination address */
m_stDstAddr.sin_family = AF_INET;
m_stDstAddr.sin_addr.s_addr = inet_addr(lpDstAddr);
m_stDstAddr.sin_port = htons(uDstPort);
//广播
if(strstr(lpDstAddr,"255"))
{
BOOL bEnable = TRUE ;
int nRes = setsockopt(m_socket,SOL_SOCKET,SO_BROADCAST,(const char*)&bEnable,sizeof(bEnable));

}
//
else
{
// note the 2 says how many concurrent cpu bound threads to allow thru
// this should be tunable based on the requests. CPU bound requests will
// really really honor this.
//
JoinMultiCastGroup(lpDstAddr,uDstPort);
}
//* Disable loopback */
//*/
BOOL fFlag = FALSE;
int nRet = setsockopt(m_socket,
IPPROTO_IP,
IP_MULTICAST_LOOP,
(char *)&fFlag,
sizeof(fFlag));
if (nRet == SOCKET_ERROR) {
printf ("setsockopt() IP_MULTICAST_LOOP failed, Err: %d\n",
WSAGetLastError());
return false ;
}
//*/
//
return CreateCompleteIO();
}

bool CUdpSocket::JoinMultiCastGroup(LPCTSTR lpDstAddr, USHORT uDstPort)
{
/* Assign our destination address */
m_stDstAddr.sin_family = AF_INET;
m_stDstAddr.sin_addr.s_addr = inet_addr(lpDstAddr);

m_stDstAddr.sin_port = htons(uDstPort);

struct ip_mreq stMreq; /* Multicast interface structure */
/* Join the multicast group
*
* NOTE: According to RFC 1112, a sender does not need to join the
* group, however Microsoft requires a socket to join a group in
* order to use setsockopt() IP_MULTICAST_TTL (or fails with error
* WSAEINVAL).
*/
stMreq.imr_multiaddr.s_addr = inet_addr(lpDstAddr);
stMreq.imr_interface.s_addr = INADDR_ANY;
int nRet = setsockopt(m_socket,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
(char *)&stMreq,
sizeof(stMreq));
if (nRet == SOCKET_ERROR) {
printf (
"setsockopt() IP_ADD_MEMBERSHIP address %s failed, Err: %d\n",
lpDstAddr, WSAGetLastError());
return false ;
}

/* Set IP TTL to traverse up to multiple routers */
//*
u_long lTTL = 2 ;
nRet = setsockopt(m_socket,
IPPROTO_IP,
IP_MULTICAST_TTL,
(char *)<TL,
sizeof(lTTL));
if (nRet == SOCKET_ERROR) {
printf ("setsockopt() IP_MULTICAST_TTL failed, Err: %d\n",
WSAGetLastError());
}
//*/

return true ;

}
//
bool CUdpSocket::CreateCompleteIO()
{
m_hCompletionPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE,NULL,0,1);
if (!m_hCompletionPort)
{
printf ("m_hCompletionPort Create Failed\n");
return false;
}

//Associate this socket to this I/O completion port
CreateIoCompletionPort ((HANDLE)m_socket,m_hCompletionPort,(DWORD)m_socket,1);
return true ;

}

接收数据的线程:
DWORD CReceiveSocket::DoWork()
{
DWORD nSocket;
BOOL b;
OVERLAPPED ovl;
LPOVERLAPPED lpo = &ovl;
DWORD dwTransfered = 0 ;
DWORD dwToTransfer = 0 ;
BYTE ReadBuffer[BUF_SIZE] ;
LPVOID lpMsgBuf;
DWORD dwBytes = AUDIO_PACKET_SIZE + sizeof(ST_FRAME);
for(;;)
{
b = GetQueuedCompletionStatus (m_hCompletionPort,&dwToTransfer,&nSocket,&lpo,INFINITE);
if(b || lpo)
{
OVERLAPPED ol;
ol.hEvent = m_hEvent;
ol.Offset = 0;
ol.OffsetHigh = 0;
memset(ReadBuffer,0,BUF_SIZE);
b = ReadFile ((HANDLE)nSocket,ReadBuffer,dwToTransfer,&dwTransfered,&ol);
if (!b )
{
DWORD dwErrCode = GetLastError();
if( dwErrCode != ERROR_IO_PENDING )
{
// something has gone wrong here...
printf("Something has gone wrong:Error code - %d\n",dwErrCode );

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErrCode ,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);

OutputDebugString((LPCTSTR)lpMsgBuf);

// Free the buffer.
LocalFree( lpMsgBuf );
return -1 ;

}
else if( dwErrCode == ERROR_IO_PENDING && m_pIncomingDataHandler )
{
WaitForSingleObject(ol.hEvent,INFINITE);
m_pIncomingDataHandler(m_dwParam,ReadBuffer,dwBytes);
}
}
else if(m_pIncomingDataHandler)
{
m_pIncomingDataHandler(m_dwParam,ReadBuffer,dwBytes);
}
continue;
}
else
{
fprintf (stdout, "WorkThread Wait Failed\n");
return -1 ;
}
}
TRACE("RECV THREAD EXIT!\n");
return 0 ;
}
...全文
635 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
MTomato 2011-07-20
  • 打赏
  • 举报
回复
最后发现是组播接收数据时,没有绑定到对应网卡,俺的错啊
jsjygm 2011-07-20
  • 打赏
  • 举报
回复

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧