BOOL My_WSAJoinLeaf() { SOCKET s=NULL; const struct sockaddr FAR * name=NULL; int namelen=NULL; LPWSABUF lpCallerData=NULL; LPWSABUF lpCalleeData=NULL; LPQOS lpSQOS=NULL; LPQOS lpGQOS=NULL; DWORD dwFlags=NULL; SOCKET returnVal_Real = NULL; SOCKET returnVal_Intercepted = NULL; DWORD error_Real = 0; DWORD error_Intercepted = 0; __try{ disableInterception(); returnVal_Real = WSAJoinLeaf (s,name,namelen,lpCallerData,lpCalleeData,lpSQOS,lpGQOS,dwFlags); error_Real = GetLastError(); enableInterception(); returnVal_Intercepted = WSAJoinLeaf (s,name,namelen,lpCallerData,lpCalleeData,lpSQOS,lpGQOS,dwFlags); error_Intercepted = GetLastError(); }__except(puts("in filter"), 1){puts("exception caught");} return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted)); }
BOOL CURtpMulticastMediaFramesSource::Connect(CString & sError) { BOOL bRet = CUTcpMediaFramesSource::Connect(sError); if(!bRet) return FALSE; try { MulticastGroupDescription grDesc; ZeroMemory(&grDesc, sizeof(MulticastGroupDescription)); if(!ReadBytes((BYTE *)&grDesc, sizeof(MulticastGroupDescription))) throw(_T("Media server dropped connection")); if(grDesc.nPort != 0) { // Create the socket. In Winsock 2 we do have to specify the // multicast attributes that this socket will be used with. if ((m_sock = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) throw(_T("Winsock multicast error - can't create datagram socket")); //Disable loopback int optval = 0; if(setsockopt(m_sock, IPPROTO_IP, 4, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) throw(_T("Winsock multicast error - can't disable loopback")); //Enlarge receive buffer optval = 0x20000; if(setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) { optval = 0x10000; if(setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) { optval = 0x8000; setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, (char *)&optval, sizeof(optval)); } } //Allow multiple viewers BOOL bReuse = TRUE; setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(BOOL)); // Setup the SOCKADDR_IN structure describing the multicast // group we want to join. sockaddr_in remote = {0}; remote.sin_family = AF_INET; remote.sin_port = htons(grDesc.nPort); remote.sin_addr.s_addr = inet_addr(grDesc.chGroup); // Join the multicast group. sockM is not used to send // or receive data. It is used when you want to leave the // multicast group. Simply call closesocket() on it to // unsubscribe from the group. if((m_sockM = WSAJoinLeaf(m_sock, (SOCKADDR *)&remote, sizeof(remote), NULL, NULL, NULL, NULL, JL_RECEIVER_ONLY)) == INVALID_SOCKET) throw(_T("Winsock multicast error - can't join multicast group")); } } catch(const LPTSTR & sMessage) { sError = sMessage; bRet = FALSE; } catch(...) { sError = _T("Unexpected error"); bRet = FALSE; } return bRet; }
// // Function: Server // // Description: // Bind to the local interface and then invite each leaf // address which was specified on the command line. // Once each connection is made, send some data. // void Server(SOCKET s, WSAPROTOCOL_INFO *lpSocketProtocol) { // Server routine // SOCKADDR_ATM atmleaf, atmroot; WSABUF wsasend; char sendbuf[BUFSIZE], szAddr[BUFSIZE]; DWORD dwBytesSent, dwAddrLen=BUFSIZE, dwNumInterfaces, i; int ret; // If no specified local interface is given pick the first // one // memset(&atmroot, 0, sizeof(SOCKADDR_ATM)); if (!bLocalAddress) { dwNumInterfaces = GetNumATMInterfaces(s); GetATMAddress(s, 0, &atmroot.satm_number); } else AtoH((char *)&atmroot.satm_number.Addr[0], szLocalAddress, ATM_ADDR_SIZE-1); // // Set the port number in the address structure // AtoH((char *)&atmroot.satm_number.Addr[ATM_ADDR_SIZE-1], szPort, 1); // // Fill in the rest of the SOCKADDR_ATM structure // atmroot.satm_family = AF_ATM; atmroot.satm_number.AddressType = ATM_NSAP; atmroot.satm_number.NumofDigits = ATM_ADDR_SIZE; atmroot.satm_blli.Layer2Protocol = SAP_FIELD_ANY; atmroot.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; atmroot.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; // // Print out what we're binding to and bind() // if (WSAAddressToString((LPSOCKADDR)&atmroot, sizeof(atmroot), lpSocketProtocol, szAddr, &dwAddrLen)) { printf("WSAAddressToString failed: %d\n", WSAGetLastError()); } printf("Binding to: <%s>\n", szAddr); if (bind(s, (SOCKADDR *)&atmroot, sizeof(SOCKADDR_ATM)) == SOCKET_ERROR) { printf("bind() failed: %d\n", WSAGetLastError()); return; } // Invite each leaf // for(i=0; i < dwAddrCount ;i++) { // Fill in the SOCKADR_ATM structure for each leaf // memset(&atmleaf, 0, sizeof(SOCKADDR_ATM)); AtoH((char *)&atmleaf.satm_number.Addr[0], szLeafAddresses[i], ATM_ADDR_SIZE-1); AtoH((char *)&atmleaf.satm_number.Addr[ATM_ADDR_SIZE-1], szPort, 1); atmleaf.satm_family = AF_ATM; atmleaf.satm_number.AddressType = ATM_NSAP; atmleaf.satm_number.NumofDigits = ATM_ADDR_SIZE; atmleaf.satm_blli.Layer2Protocol = SAP_FIELD_ANY; atmleaf.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; atmleaf.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; // // Print out clients address and the invite it // if (WSAAddressToString((LPSOCKADDR)&atmleaf, sizeof(atmleaf), lpSocketProtocol, szAddr, &dwAddrLen)) { printf("WSAAddressToString failed: %d\n", WSAGetLastError()); } printf("[%02d] Inviting: <%s>\n", i, szAddr); if ((sLeafSock[i] = WSAJoinLeaf(s, (SOCKADDR *)&atmleaf, sizeof(SOCKADDR_ATM), NULL, NULL, NULL, NULL, JL_SENDER_ONLY)) == INVALID_SOCKET) { printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError()); WSACleanup(); return; } } // Note that the ATM protocol is a bit different that TCP. // When the WSAJoinLeaf (or connect call) completes the // peer has not necessarily accepted the connection yet // so immediately sending data will result in an error // which is why we wait a short bit. // printf("Press a key to start sending."); getchar(); printf("\n"); // // Now send some data to the group address which will // be replicated to all clients // wsasend.buf = sendbuf; wsasend.len = 128; for(i=0; i < dwDataCount ;i++) { memset(sendbuf, 'a' + (i%26), 128); ret = WSASend(s, &wsasend, 1, &dwBytesSent, 0, NULL, NULL); if (ret == SOCKET_ERROR) { printf("WSASend() failed: %d\n", WSAGetLastError()); break; } printf("[%02d] Wrote: %d bytes\n", i, dwBytesSent); Sleep(500); } for(i=0; i < dwAddrCount ;i++) closesocket(sLeafSock[i]); return; }
/* begin a comms session */ ComAPIHandle ComIPMulticastOpen(int buffersize, char *gamename, int mc_scope) { LPWSAPROTOCOL_INFO protocols = 0; LPWSAPROTOCOL_INFO mc_protocol = 0; int numProtocols = 0; ComIP *c; int i, err; int trueValue=1; int falseValue=0; c = (ComIP*)malloc(sizeof(ComIP)); if (InitWS2(&c->wsaData) == 0 || FindProtocols(&protocols, &numProtocols) == 0) { free(c); return 0; } /* verify that we have a multi-cast protocol */ /* for (i = 0; i < numProtocols && mc_protocol == 0; i++) { */ for (i = 0; i < numProtocols; i++) { if (!mc_protocol && protocols[i].dwServiceFlags1 & XP1_SUPPORT_MULTIPOINT && !(protocols[i].dwServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) && !(protocols[i].dwServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE)) { mc_protocol = &protocols[i]; #ifdef DEBUG_COMMS printf("Found a suitable protocol:\n"); printf(" iProtocol = %d\n", mc_protocol->iProtocol); printf(" iSocketType = %d\n", mc_protocol->iSocketType); printf(" iAddressFamily = %d\n", mc_protocol->iAddressFamily); printf(" flags = 0x%x\n", mc_protocol->dwServiceFlags1); printf(" msgsize = %d\n", mc_protocol->dwMessageSize); printf(" name = '%s'\n", mc_protocol->szProtocol); } else { printf("Unsuitable protocol:\n"); printf(" iProtocol = %d\n", protocols[i].iProtocol); printf(" flags = 0x%x\n", protocols[i].dwServiceFlags1); printf(" msgsize = %d\n", protocols[i].dwMessageSize); printf(" name = '%s'\n", protocols[i].szProtocol); #endif } } if (mc_protocol == 0) { #ifdef DEBUG_COMMS printf("ComMulticastOpen: Found no suitable protocols\n"); #endif free(protocols); free(c); return 0; } /* initialize header data */ c->apiheader.protocol = CAPI_IP_MULTICAST_PROTOCOL; c->apiheader.send_func = ComIPMulticastSend; c->apiheader.recv_func = ComIPMulticastGet; c->apiheader.send_buf_func = ComIPSendBufferGet; c->apiheader.recv_buf_func = ComIPRecvBufferGet; c->apiheader.addr_func = ComIPHostIDGet; c->apiheader.close_func = ComIPMulticastClose; c->buffer_size = sizeof(ComAPIHeader) + buffersize; c->send_buffer.buf = (char *)malloc(c->buffer_size); ComIPHostIDGet(&c->apiheader, c->send_buffer.buf); #ifdef DEBUG_COMMS printf("ComAPIOpen -- got id 0x%x\n", ((ComAPIHeader *)c->send_buffer.buf)->sender); #endif strncpy(((ComAPIHeader *)c->send_buffer.buf)->gamename, gamename, GAME_NAME_LENGTH); c->recv_buffer.buf = (char *)malloc(c->buffer_size); /* Incoming... */ #if 1 c->recv_sock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, 0, #else c->recv_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, mc_protocol, 0, #endif WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF); if(c->recv_sock == INVALID_SOCKET) { err = WSAGetLastError(); free(protocols); free(c); return 0; } memset ((char*)&comRecvAddr, 0, sizeof(comRecvAddr)); /* comRecvAddr.sin_family = mc_protocol->iAddressFamily; */ comRecvAddr.sin_family = AF_INET; comRecvAddr.sin_addr.s_addr = htonl(0x9d000001); comRecvAddr.sin_addr.s_addr = htonl(0x0); comRecvAddr.sin_port = htons(CAPI_UDP_PORT); #ifdef DEBUG_COMMS printf("binding (recv) socket #%d\n", c->recv_sock); #endif if(err=bind(c->recv_sock, (struct sockaddr*)&comRecvAddr,sizeof(comRecvAddr))) { err = WSAGetLastError(); #ifdef DEBUG_COMMS printf("bind (recv) error #%d\n", err); #endif free(protocols); free(c); return 0; } /* WSAIoctl(c->recv_sock, FIONBIO, &trueValue, sizeof(trueValue), 0, 0, 0, 0, 0); */ WSAIoctl(c->recv_sock, SIO_MULTIPOINT_LOOPBACK, &falseValue, sizeof(falseValue), 0, 0, 0, 0, 0); WSAIoctl(c->recv_sock, SIO_MULTICAST_SCOPE, &mc_scope, sizeof(mc_scope), 0, 0, 0, 0, 0); c->send_sock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, 0, WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF); if(c->send_sock == INVALID_SOCKET) { err = WSAGetLastError(); free(protocols); free(c); return 0; } /* Outgoing... */ memset ((char*)&comSendAddr, 0, sizeof(comSendAddr)); comSendAddr.sin_family = AF_INET; /* comSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); */ comSendAddr.sin_addr.s_addr = htonl(0xe0000001); comSendAddr.sin_port = htons(CAPI_UDP_PORT); /* setsockopt(c->send_sock, SOL_SOCKET, SO_BROADCAST, */ /* (char *)&trueValue, sizeof(int) ); */ c->recv_sock = WSAJoinLeaf(c->recv_sock, (struct sockaddr *)&comRecvAddr, sizeof(comRecvAddr), 0, 0, 0, 0, JL_BOTH); /* 0, 0, 0, 0, JL_RECEIVER_ONLY); */ if (c->recv_sock == INVALID_SOCKET) { err = WSAGetLastError(); #ifdef DEBUG_COMMS printf("WSAJoinLeaf (recv) error #%d\n", err); #endif free(protocols); free(c); return 0; } WSAIoctl(c->recv_sock, FIONBIO, &trueValue, sizeof(trueValue), 0, 0, 0, 0, 0); free(protocols); return (ComAPIHandle)c; }
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框 UINT ThreadFun(LPVOID pParam){ //线程要调用的函数 WSADATA wsd; int len=sizeof(struct sockaddr_in); int ret; TCHAR recvbuf[BUFSIZE]; if(WSAStartup(MAKEWORD(2,2),&wsd)!=0) { printf("WSAStartup()failed\n"); return -1; } if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0, WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF| WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) { printf("socket failed with :%d\n",WSAGetLastError()); WSACleanup(); return -1; } //将sock绑定到本机端口上 local.sin_family=AF_INET; local.sin_port=htons(MCASTPORT); local.sin_addr.s_addr=INADDR_ANY; if(bind(sock,(struct sockaddr*)&local,sizeof(local))==SOCKET_ERROR) { printf("bind failed with %d\n",WSAGetLastError()); closesocket(sock); WSACleanup(); return -1; } //加入多播组 remote.sin_family=AF_INET; remote.sin_port=htons(MCASTPORT); remote.sin_addr.s_addr=inet_addr(MCASTADDR); if((sockM=WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote), NULL,NULL,NULL,NULL, JL_BOTH))==INVALID_SOCKET) { printf("WSAJoinLeaf()failed:%d\n",WSAGetLastError()); closesocket(sock); WSACleanup(); return -1; } //接收多播数据,当收到的数据为QUIT时退出 while(1) { if((ret=recvfrom(sock,recvbuf,BUFSIZE,0, (struct sockaddr*)&from,&len))==SOCKET_ERROR) { //printf("recvfrom failed with :%d\n",WSAGetLastError()); closesocket(sockM); closesocket(sock); WSACleanup(); return -1; } if(strcmp(recvbuf,"QUIT")==0) break; else{ recvbuf[ret]='\0'; Str+=inet_ntoa(from.sin_addr); Str+=":"; Str+=recvbuf; Str+="\r\n"; HWND hWnd = GetDlgItem(AfxGetMainWnd()->m_hWnd,IDC_EDIT1); CWnd *pWnd = CWnd::FromHandle(hWnd); pWnd->SetWindowText(_T(Str)); } } closesocket(sockM); closesocket(sock); WSACleanup(); return 0; }
int TPMulticastClient::Connect(const char* szIp, int nPort) { if (szIp == NULL) { m_remoteIp = INADDR_ANY; } else { m_remoteIp = inet_addr(szIp); } m_remotePort = htons(nPort); // Winsock1.1 // // 先create // int nRet = Create(opMode_udp); // if (nRet < 0) // { // return -1; // } // // // // 加入多播组 // struct ip_mreq mcast; // int optval = 8; // // mcast.imr_multiaddr.s_addr = m_remoteIp; // 组的IP多播地址 // mcast.imr_interface.s_addr = m_localIp; // 接口的本地IP地址 // // nRet = setsockopt(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(struct ip_mreq)); // if (nRet == SOCKET_ERROR) // { // goto e_clean; // } // // nRet = setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&optval, sizeof(int)); // if (nRet == SOCKET_ERROR) // { // goto e_clean; // } // // optval = 0; // nRet = setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&optval, sizeof(optval)); // if (nRet == SOCKET_ERROR) // { // goto e_clean; // } // Winsock2.0 // 先create m_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED); if (m_socket == INVALID_SOCKET) { return -1; } // 绑定套接字地址和端口 if (m_localIp != INADDR_ANY && m_localPort != 0) { struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(struct sockaddr_in)); local_addr.sin_family = AF_INET; local_addr.sin_port = m_localPort; local_addr.sin_addr.s_addr = m_localIp; if (INVALID_SOCKET == bind(m_socket, (struct sockaddr *)&local_addr, sizeof(struct sockaddr))) { closesocket(m_socket); m_socket = INVALID_SOCKET; return -1; } } else { // 必须绑定为组播端口号 char szLocalIp[32] = {0}; int ret = GetLocalIP(szLocalIp); if (ret < 0) { closesocket(m_socket); m_socket = INVALID_SOCKET; return -1; } m_localIp = inet_addr(szLocalIp); struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(struct sockaddr_in)); local_addr.sin_family = AF_INET; local_addr.sin_port = m_remotePort; local_addr.sin_addr.s_addr = m_localIp; if (INVALID_SOCKET == bind(m_socket, (struct sockaddr *)&local_addr, sizeof(struct sockaddr))) { closesocket(m_socket); m_socket = INVALID_SOCKET; return -1; } } // 设为非阻塞模式 unsigned long flags = 1; int nRet = ioctlsocket(m_socket, FIONBIO, &flags); if (nRet != 0) { closesocket(m_socket); m_socket = INVALID_SOCKET; return -1; } if(m_recvBuffSize > 0) setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char*)&m_recvBuffSize, sizeof(int)); if(m_sendBuffSize > 0) setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (char*)&m_sendBuffSize, sizeof(int)); // 加入多播组 struct sockaddr_in remote_addr; memset(&remote_addr, 0, sizeof(struct sockaddr_in)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = m_remotePort; remote_addr.sin_addr.s_addr = m_remoteIp; m_sockMultipoint = WSAJoinLeaf(m_socket, (SOCKADDR*)&remote_addr, sizeof(struct sockaddr_in), NULL, NULL, NULL, NULL, JL_BOTH); if (m_sockMultipoint == INVALID_SOCKET) { closesocket(m_socket); m_socket = INVALID_SOCKET; return -1; } // 再创建客户端环境 nRet = CreateClientEnvironment(); if (nRet < 0) { goto e_clean; } // 然后将socket添加到完成端口中 nRet = AddSocketToIOCP(m_socket, m_pPerHandleData); if (nRet >= 0) { m_pPerHandleData->AddRef(); m_pPerIoRecv->AddRef(); nRet = PostRecvToIOCP(m_socket, m_pPerIoRecv); if (nRet < 0) { m_pPerIoRecv->DecRef(); m_pPerHandleData->DecRef(); ClearClientEnvironment(); goto e_clean; } } else { ClearClientEnvironment(); goto e_clean; } return 1; e_clean: DelSocketFromIOCP(m_socket, m_pPerHandleData); m_socket = INVALID_SOCKET; return -1; }
void C多播收发:刘兴龙Dlg::OnBnClickedRadio1() { // 接收消息上线 if (Setinfo==0){ MessageBox(L"还未设置好,请先设置!"); CButton* radio = (CButton*)GetDlgItem(IDC_RADIO1); radio->SetCheck(0); } else{ if (flag == 0){ flag = 1; str = L""; UpdateData(FALSE); /* struct ip_mreq mcast;// Winsock1.0 */ //初始化 WinSock2.2 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){ //printf("WSAStartup() failed\n"); flag = 0; MessageBox(L"Sock 初始化失败!"); return; } /* 创建一个SOCK_DGRAM类型的SOCKET 其中,WSA_FLAG_MULTIPOINT_C_LEAF 表示 IP 多播在控制面层上属于“无根”类型; WSA_FLAG_MULTIPOINT_D_LEAF 表示 IP 多播在数据面层上属于“无根”,有关控制面层和 数据面层有关概念请阅读MSDN说明 */ if ((sock = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET){ //printf("socket failed with:%d\n", WSAGetLastError()); WSACleanup(); flag = 0; MessageBox(L"Socket 创建失败!"); return; } //将 sock 绑定到本机某端口上。 local.sin_family = AF_INET; local.sin_port = htons(MCASTPORT); local.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR){ //printf("bind failed with:%d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); flag = 0; // AfxEndThread(0); MessageBox(L"Sock 绑定本机端口失败!"); return; } //加入多播组 remote.sin_family = AF_INET; remote.sin_port = htons(MCASTPORT); remote.sin_addr.s_addr = inet_addr(MCASTADDR); /* Winsock2.0 */ if ((sockM = WSAJoinLeaf(sock, (SOCKADDR*)&remote, sizeof(remote), NULL, NULL, NULL, NULL, JL_BOTH)) == INVALID_SOCKET){ //printf("WSAJoinLeaf() failed:%d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); flag = 0; MessageBox(L"加入播数组失败!"); return; } MessageBox(L"上线成功!"); AfxBeginThread(TestThreadFun, this); }else{ MessageBox(L"以是上线状态了!"); } } }