* SOL_SOCKET
| optname | optval类型 |
| ------------------------------------------ | -------------- |
| **SO_BROADCAST** 允许发送广播数据 | int |
| SO_DEBUG 允许调试 | int |
| SO_DONTROUTE 不查找路由 | int |
| SO_ERROR 获得套接字错误 | int |
| SO_KEEPALIVE 保持连接 | int |
| SO_LINGER 延迟关闭连接 | struct linger |
| SO_OOBINLINE 带外数据放入正常数据流 | int |
| SO_RCVBUF 接收缓冲区大小 | int |
| SO_SNDBUF 发送缓冲区大小 | int |
| SO_RCVLOWAT 接收缓冲区下限 | int |
| SO_SNDLOWAT 发送缓冲区下限 | int |
| SO_RCVTIMEO 接收超时 | struct timeval |
| SO_SNDTIMEO 发送超时 | struct timeval |
| **SO_REUSEADDR** 允许重用本地地址和端口 | int |
| SO_TYPE 获得套接字类型 | int |
| SO_BSDCOMPAT 与BSD系统兼容 | int |
* IPPROTO_IP
| optname | optval类型 |
| -------------------------------------------------- | -------------- |
| IP_ADD_MEMBERSHIP 将指定IP加入到组播组中 | struct ip_mreq |
| IP_MULTICAST_IF 允许开启组播报文的接口 | struct ip_mreq |
* IPPRO_TCP
| optname | optval类型 |
| ------------------------------- | ---------- |
| TCP_MAXSEG TCP最大数据段的大小 | int |
| TCP_NODELAY 不使用Nagle算法 | int |
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//创建用户数据报套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
//缺省创建的套接字不允许广播数据包,需要设置属性
//setsockopt可以设置套接字属性
int opt = 1;
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));
//接收方地址指定为广播地址 指定端口信息
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8848);
saddr.sin_addr.s_addr = inet_addr("192.168.7.255");
//循环发送数据包
char sendBuf[32] = {0};
while(1)
{
read(0,sendBuf,sizeof(sendBuf));
sendto(sockfd,sendBuf,sizeof(sendBuf),0,(struct sockaddr *)&saddr,sizeof(saddr));
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//创建用户数据报套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
//绑定IP地址(广播IP或0.0.0.0)和端口
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8848);
saddr.sin_addr.s_addr = inet_addr("192.168.7.255");
//绑定的端口必须和发送方指定的端口相同
bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr));
//等待接收数据
char recvBuf[32] = {0};
while(1)
{
recvfrom(sockfd,recvBuf,sizeof(recvBuf),0,NULL,NULL);
printf("recvBuf:%s\n",recvBuf);
memset(recvBuf,0,sizeof(recvBuf));
}
return 0;
}
广播方式发给所有主机,过多的广播会占用大量的网络带宽,造成广播风暴,影响正常通信。
组播又称为多播,是一种折中的方式,只有加入某个多播组的主机才能接收到数据。
多播方式既可以发给多个主机,又能避免像广播那样带来过多的负载(每台主机要到传输层才能判断广播包是否要处理)。
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//创建用户数据报套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
//接收方地址指定为组播地址 指定端口信息 224.10.10.10
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8848);
saddr.sin_addr.s_addr = inet_addr("224.10.10.10");
//发送数据包
char sendBuf[32] = {0};
while(1)
{
read(0,sendBuf,sizeof(sendBuf));
sendto(sockfd,sendBuf,sizeof(sendBuf),0,(struct sockaddr *)&saddr,sizeof(saddr));
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//创建用户数据报套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
//加入多播组
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.10");
mreq.imr_interface.s_addr = inet_addr("0.0.0.0");
setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
//绑定IP地址(加入组的组IP或0.0.0.0)和端口 绑定的端口必须和发送方指定的端口相同
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8848);
saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr));
//等待接收数据
char recvBuf[32] = {0};
while(1)
{
recvfrom(sockfd,recvBuf,sizeof(recvBuf),0,NULL,NULL);
printf("recvBuf:%s\n",recvBuf);
memset(recvBuf,0,sizeof(recvBuf));
}
return 0;
}