//初始化IP组播套接字
int CPlayApp::InitMultiSocket()
{
int SendBuf;
DWORD cbRet;
int status;
BOOL bFlag;
SOCKADDR_IN SrcAddr;
CMainFrame* pFrame=(CMainFrame*)m_pMainWnd;
HWND m_hwnd=pFrame->m_hWnd;
//创建一个IP组播套接字
MultiSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
(LPWSAPROTOCOL_INFO)NULL, 0,
WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
if (MultiSock == INVALID_SOCKET)
{
ErrMsg(m_hwnd,"WSASocket Error");
return -1;
}
//设置套接字为可重用端口地址
bFlag = TRUE;
status = setsockopt(
MultiSock,
SOL_SOCKET,
SO_REUSEADDR,
(char *)&bFlag,
sizeof (bFlag));
if (status == SOCKET_ERROR)
{
ErrMsg(m_hwnd,"setsockopt Error");
return -1;
}
// 将套接字绑扎到用户指定端口及默认的接口
SrcAddr.sin_family = AF_INET;
SrcAddr.sin_port = htons (DESTPORT);
SrcAddr.sin_addr.s_addr = INADDR_ANY;
status = bind (
MultiSock,
(struct sockaddr FAR *)&SrcAddr,
sizeof(struct sockaddr));
if (status == SOCKET_ERROR)
{
ErrMsg(m_hwnd,"bind Error");
return -1;
}
nIP_TTL = 2; //允许跨网传播
// 设置多址广播数据报传播范围,允许跨网传播
status = WSAIoctl (MultiSock,
SIO_MULTICAST_SCOPE,
&nIP_TTL,
sizeof (nIP_TTL),
NULL,
0,
&cbRet,
NULL,
NULL);
if (status)
{
ErrMsg(m_hwnd,"WSAIoctl Error");
return -1;
}
// 允许内部回送(LOOPBACK)
bFlag = TRUE;
status = WSAIoctl (MultiSock, /* socket */
SIO_MULTIPOINT_LOOPBACK, /* LoopBack on or off */
&bFlag, /* input */
sizeof (bFlag), /* size */
NULL, /* output */
0, /* size */
&cbRet, /* bytes returned */
NULL, /* overlapped */
NULL); /* completion routine */
if (status)
{
ErrMsg(m_hwnd,"WSAIoctl Error");
return -1;
}
//设定发送缓冲区为64k
SendBuf=65536;
status = setsockopt(
MultiSock,
SOL_SOCKET,
SO_SNDBUF,
(char *)&SendBuf,
sizeof(SendBuf));
if (status == SOCKET_ERROR)
{
ErrMsg(m_hwnd,"setsockopt Error");
return -1;
}
//测试设定的发送缓冲区是否为64k
int ASendBuf;
int SLen=sizeof(ASendBuf);
status=getsockopt(MultiSock,SOL_SOCKET,SO_SNDBUF,
(char * )&ASendBuf, &SLen);
if (status == SOCKET_ERROR)
{
ErrMsg(m_hwnd,"setsockopt Error");
return -1;
}
if(status==0)
{
if(ASendBuf!=65536)
return -1;
}
DestAddr.sin_family = AF_INET;
DestAddr.sin_port = htons (DESTPORT);
DestAddr.sin_addr.s_addr =inet_addr(MULTIDESTADDR);
return 0;
}