www.gusucode.com > 一些VC++网络编程实例源代码-源码程序 > 一些VC++网络编程实例源代码-源码程序\code\第九章\MultiCastChat\MultiCast.cpp
//Download by http://www.NewXing.com // MultiCast.cpp: implementation of the CMultiCast class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MultiCastChat.h" #include "MultiCast.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMultiCast::CMultiCast() { m_hWnd = NULL; m_bConnected = FALSE; } CMultiCast::~CMultiCast() { } BOOL CMultiCast::Create(CString lpstrAddr, unsigned short port, HWND hWnd) { if(m_bConnected){ TRACE("Has Successfully Create the socket!\n"); return FALSE; } m_hWnd = hWnd; int ret; // 将字符串地址转换为套接字地址 int iLen = 0; int cbRet = 0; int nIP_TTL = 16;//设置IP数据生存期 BOOL bFlag; iLen = sizeof(addr); m_hSocket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); if (m_hSocket == INVALID_SOCKET){ TRACE("WSASocket:%d\n",WSAGetLastError()); return FALSE; } bFlag = TRUE; // 设置套接字为可重用端口地址 ret = setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&bFlag, sizeof (bFlag)); if(ret == SOCKET_ERROR){ TRACE("setsockopt:%d",WSAGetLastError()); return FALSE; } // 将套接字绑扎到用户指定端口及默认的接口 addr.sin_family = PF_INET; addr.sin_port = htons (port); addr.sin_addr.s_addr = INADDR_ANY; ret = bind (m_hSocket, (struct sockaddr FAR *)&addr, sizeof(struct sockaddr)); if (ret == SOCKET_ERROR){ TRACE("bind: %d", WSAGetLastError()); return FALSE; } // 设置多址广播数据报传播范围(TTL) ret = WSAIoctl(m_hSocket, SIO_MULTICAST_SCOPE, &nIP_TTL, sizeof (nIP_TTL), NULL, 0, (unsigned long*)&cbRet, NULL, NULL); if (ret == SOCKET_ERROR){ TRACE("SAIoctl(SIO_MULTICAST_SCOPE):%d\n",WSAGetLastError()); return FALSE; } char* chAddr = lpstrAddr.GetBuffer(0); ret = WSAStringToAddress(chAddr, AF_INET, NULL, (LPSOCKADDR)&addr, &iLen); if(ret == SOCKET_ERROR){ m_bConnected = FALSE; TRACE("WSAStringToAddress:%d\n",WSAGetLastError()); return FALSE; } srcaddr = addr; srcaddr.sin_port = htons (port); WSABUF wsaCalleeData; m_hGroupSocket = WSAJoinLeaf(m_hSocket, (PSOCKADDR)&addr, sizeof(addr), NULL, &wsaCalleeData, NULL, NULL, JL_BOTH); if (m_hGroupSocket == INVALID_SOCKET){ m_bConnected = FALSE; TRACE("WSAJoinLeaf():%d\n", WSAGetLastError()); return FALSE; } ret = WSAAsyncSelect(m_hGroupSocket, m_hWnd, WM_MULTIPOINTEVENT, FD_WRITE | FD_READ | FD_QOS | FD_GROUP_QOS | FD_CONNECT); if(ret == SOCKET_ERROR){ TRACE("WSAAsyncSelect():%d\n", WSAGetLastError()); m_bConnected = FALSE; return FALSE; } m_bConnected = TRUE; return TRUE; } int CMultiCast::Send(char *lpData, int size) { if(m_hSocket == INVALID_SOCKET) return -1; unsigned long nDataSent = 0; int nReturnCode; WSABUF wsaBuf; wsaBuf.len = size; wsaBuf.buf = lpData; nReturnCode = WSASendTo(m_hSocket, &wsaBuf, 1, &nDataSent, 0, (LPSOCKADDR)&srcaddr, sizeof(SOCKADDR), NULL, NULL); if(nReturnCode == SOCKET_ERROR){ TRACE0("Error in send packets to the network!\n"); return -1; } return nDataSent; } int CMultiCast::Receive(char *lpData, int size) { int nReturnCode ; WSABUF wsaRecvBuf; wsaRecvBuf.buf = lpData; wsaRecvBuf.len = size; unsigned long cbRet = 0; int iLen = sizeof (srcaddr); int dFlag = 0; nReturnCode = WSARecvFrom(m_hGroupSocket, &wsaRecvBuf, 1, &cbRet, (unsigned long*)&dFlag, (struct sockaddr *)&srcaddr, &iLen, NULL, NULL); if(nReturnCode == SOCKET_ERROR){ if(WSAEWOULDBLOCK == WSAGetLastError()) TRACE("Socket will block!\n"); else{ if(WSAGetLastError() == WSA_IO_PENDING) TRACE("IO is pending!\n"); else return -1; } TRACE("RecvFrom Error:%d\n", WSAGetLastError()); } //本次操作没有接收到数据 if(cbRet == 0) return 0; //通知父窗口读数据 return cbRet; } void CMultiCast::Initilize() { WSADATA wsaData; WORD version = MAKEWORD(2, 0); int ret = WSAStartup(version, &wsaData); if(ret != 0) TRACE("Initilize Error!\n"); } void CMultiCast::Unintilize() { if (WSACleanup() != 0){ TRACE("UnInitilize Error:%d\n", WSAGetLastError()); } } BOOL CMultiCast::IsConnected() { return m_bConnected; } void CMultiCast::Close() { closesocket(m_hSocket); closesocket(m_hGroupSocket); m_bConnected = FALSE; }