setsockopt函数

一、setsockopt函数

1.1、函数

头文件:

                 #include <sys/socket.h>
 函数:

      int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
功能:

                设置一个套接字的选项(属性)
参数:
                socket:文件描述符
                 level:协议层次
                              SOL_SOCKET      套接字层次
                              IPPROTO_TCP    TCP层次
                              IPPROTO_IP        IP层次
                option_name:选项的名称
                              SO_BROADCAST 允许发送广播数据(SOL_SOCKET层次的)
                option_value:设置的选项的值
                       第一种设置:  int类型的值,存储的是bool的数据(1和0)

                                         0 不允许
                                         1 允许

                         第二种设置: ip_mreq{}类型  

                                         struct ip_mreq
                                 {
                                   struct in_addr imr_multiaddr; //组播ip地址
                                   struct in_addr imr_interface; //主机地址    

                                    };
                                                     INADDR_ANY 任意主机地址(自动获取你的主机地址)
                   option_len:option_value的长度
返回值:
                成功:0
                失败:‐1

1.2、参数选项介绍图

二、初学者重点掌握四种设置setsockopt函数:

2.1、第一种:发送者需要设置允许用广播发送数据(用与UDP广播使用)

看1.2图所示:level选择 SOL_SOCKET   ,     optname选择  SO_BROADCAST

数据类型为int 使用第一种设置。

2.1.1、代码如下:

    int on =1;
 
   if(setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on))==-1)
   {
	   perror("fail to setsockopt");
	   exit(1);
   }

2.2、第二种:接收者需要设置setsockopt函数加入多播组(用于UDP多播使用)

看1.2图所示,level选择 IPPROTO_IP     ,    optname选择    IP_ADD_MEMBERSHIP

数据类型为 ip_mreq{} 使用第二种设置

2.2.1、代码如下:

struct ip_mreq mreq;                                
	mreq.imr_multiaddr.s_addr=inet_addr(argv[1]);   //argv[1]:传进来的是加入的多播地址
	mreq.imr_interface.s_addr=INADDR_ANY;          //INADDR_ANY:自动获取本机的地址
	socklen_t optlen =sizeof(mreq);                
 
	if(setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,optlen) < 0)
	{
		perror("fail to setsockopt");
		exit(1);
		}

2.3、第三种:设置TCP/UDP 允许重用本地地址

为什么要设置。理由:服务器和客户端正常通信时,手动异常关闭 server 端进程,再次运行开启 server 端程序会在 bind 函数位置报错,造成无法连接。

查阅资料后发现应该是地址或端口冲突了,尝试在 bind 函数前添加 setsockopt 函数增加复用功能.

经过修改测试,重用本地端口未能解决该问题,设置重用本地地址可以解决

看1.2图所示:level选择 SOL_SOCKET   ,     optname选择 SO_REUSEADDR

数据类型为int 使用第一种设置。

2.3.1、代码如下

       int on = 1;

 if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ==-1 )
  {
     perror("fail to setsockopt");
    }

2.4、第四种:设置TCP/UDP 允许重用本地端口

当我们结束一个服务器程序时,再一次打开此服务器进程同一个端口号,出现错误,必须要换一个端口号才行。

为了解决这个问题,我们需要使用setsockopt函数设置允许重用本地端口。

看1.2图所示:level选择 SOL_SOCKET   ,     optname选择 SO_REUSEPORT

数据类型为int 使用第一种设置。

2.4.1、代码如下

    int on = 1;

 if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) ==-1 )
  {
     perror("fail to setsockopt");
    }

  • 17
    点赞
  • 168
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值