int getsockopt(
SOCKET s,//套接字句柄
int level,//指定此选项被定义在哪个级别,如SIL_SOCKET、IPPROTO_TCP、IPPROTO_IP等
int optname,//套接字选项名称,如SO_ACCEPTCONN
char* optval,//指定一个缓冲区,所请求的选项的值将会被返回到这里
int* optlen//指定上面缓冲区大小,返回所需大小
);//函数调用出错返回SOCKET_ERROR
BOOL SetTimeout(SOCKET s,int nTime,BOOL bRecv)//自定义设置套接字超时值的函数
{
int ret=::setsockopt(s,SOL_SOCKET,bRecv?SO_REVTIMEO:SO_SNDTIMEO,(char*)&nTime,sizeof(nTime));
return ret!=SOCKET_ERROR;
}
int ioctlsocket(
SOCKET s,//套接字句柄
long cmd,//在套接字上要执行的命令
u_long* argp//指向cmd的参数
)
int WSAIoctl(
SOCKET s,//套接字句柄
DWORD dwIoControlCode,//在套接字上要执行的命令
LPVOID lpvInBuffer,//指向输入缓冲区
DWORD cbInBuffer,//输入缓冲区大小
LPVOID lpvOutBuffer,//指向输出缓冲区
DWORD cbOutBuffer,//输出缓冲区的大小
LPDWORD lpcbBytesReturned,//用来返回实际返回的字节数
LPWSAOVERLAPPED lpOverlapped,//指向一个WSAOVERLAPPED结构
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine//指向自定义完成例程
)
//设置SIO_RCVALL控制码,以便接收所有IP包
DWORD dwValue=1;
if(ioctlsocket(sRaw,SIO_RCBALL,&dwValue)!=0)
return;
SOCKET s=::socket(AF_INET,SOCK_DGRAM,0)
BOOL bBroadcast=TRUE;
::setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)&bBroadcast,sizeof(BOOL));
SOCKADDR_IN bcast;
bcast.sin_family=AF_INET;
bcast.sin_addr.s_addr=INVADDR_BROADCASTl
bcast.sin_port=htons(4567);
char sz[]="This is just a test\r\n";
while(TRUE){
::sendto(s,sz,strlen(sz),0,(sockaddr*)&bcast,sizeof(bcast));
::Sleep(5000);
}
SOCKET s=::socket(AF_INET,SOCK_DGRAM,0)
SOCKADDR_IN sin;
sin.sin_famoly=AF_INET;
sin.sin_addr.S_un.S_addr=INADDR_ANY;
sin.sin_port=::ntohs(4567);
if(::bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR){
print("bind() failed\n");
return ;
}
SOCKADDR_IN addrRemote;
int nLen=sizeof(addrRemote);
char sz[256];
while(TRUE){
int nRet=::recvfrom(s,sz,256,0,(sockaddr*)&addrRemote,&nLen);
if(nRet>0){
sz[nRet]=‘\0‘;
printf(sz);
}
}
typedef struct{
struct in_addr IMR_MULTIADDRl//多播组的IP地址
struct in_addr IMR_INTERFACE;//将要加入或者离开多播组的本地地址
}ip_mreq;
ip_mreq mcast;
mcast.imr_interface.S_un.S_addr=INADDR_ANY;
mcast.imr_multiaddr.S_un.S_addr=::inet_addr("234.5.6.7");
int nRet=::setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
ip_merq mcast;
mcast.imr_interface.Sun.S_addr=dwInterFace;
mcast.imr_multiaddr.Sum.S_addr=dwMultiAddr;
int nRet=::setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
BOOL bReuse=TRUE;
::setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&bReuse,sizeof(BOOL));
BOOL SetTTL(SOCKET s,int nTTL){//自定义设置多播数据TTL的函数
int nRet=::setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&nTTL,sizeof(nTTL));
return nRet!=SOCKET_ERROR;
}
struct in_addr addr;
setsockopt(sock,IPPROTO_IP,IP_MULTICAST_IF,&addr,sizeof(addr));
struct ip_mreq_source{
struct in_addr imr_multiaddr;//多播组的ip地址
struct in_addr imr_sourceaddr,//指定的源ip地址
struct in_addr imr_interface;//本地ip地址接口
}
SOCKET s=::socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
//本地接口
SOCKETADDR_IN localif;
localif.sin_family=AF_INET;
localif.sin_port=HTONS(5150);
localif.SI_ADDR.S_ADDR=HTONL(inaddr_any);
::bind(s,(SOCKADDR*)&localif,sizeof(localif));
//设置ip_mreq_source 结构
struct ip_mreq_source mreqsrc;
mreqsrc.imr_interface.s_addr=inet_addr("192.168.0.46");
mreqsrc.imr_multiaddr.s_addr=inet_addr("234.5.6.7");
//添加源地址
mreqsrc.imr_sourceaddr.s_addr=inet_addr("218.12.255.113");
::setsockopt(s,IPPROTO_IP,IP_ADD_SOURCE_MEMBERSHIP,(char*)&mreqsrc.sizeof(mreqsrc));
mreqsrc.imr_sourceaddr.s_addr=inet_addr("218.12.174.222");
::setsockopt(s,IPPROTO_IP,IP_ADD_SOURCE_MEMBERSHIP,(char*)&mreqsrc,sizeof(mreqsrc));
#include<WinSock2.h>
#include<stdio.h>
#define IP_ADD_MEMBERSHIP 12
typedef struct {
struct in_addr imr_multiaddr;//多播组的ip地址
struct in_addr imr_interface;//将要加入或者离开多播组的本地地址
}ip_mreq;
int main() {
SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0);
//允许其他进程使用绑定的地址
BOOL bReuse = TRUE;
::setsockopt(s,SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(BOOL));
//绑定到4567端口
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = ::ntohs(4567);
si.sin_addr.S_un.S_addr = INADDR_ANY;
::bind(s, (sockaddr*)&si, sizeof(si));
//加入多播组
ip_mreq mcast;
mcast.imr_interface.S_un.S_addr = INADDR_ANY;
mcast.imr_multiaddr.S_un.S_addr = ::inet_addr("234.5.6.7");//多播地址
::setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast));
//接收多播数据
printf("开始接收多播组234.5.6.7上的数据");
char buf[1280];
int nAddrLen(sizeof(si));
while (TRUE)
{
int nRet = ::recvfrom(s, buf, strlen(buf), 0, (sockaddr*)&si, &nAddrLen);
if (nRet!=SOCKET_ERROR)
{
buf[nRet] = ‘\0‘;
printf(buf);
}
else
{
int i = ::WSAGetLastError();
break;
}
}
return 0;
}
原文:https://www.cnblogs.com/binarysystemloophole/p/13508339.html