socket属性设置

来源:互联网 发布:外盘配资端口 编辑:程序博客网 时间:2024/06/05 14:35

//设置socket属性

int getsockopt(intsockfd, int level, int optname,void *optval, socklen_t *optlen);

int setsockopt(intsockfd, int level, int optname,const void *optval, socklen_t optlen);

 

功能:

    获得或是设置socket属性

 

 参数:

    @sockfd 要设置的socket

    @level  socket 层次

             SOL_SOCKET   //通用的socket选项

             IPPROTO_IP   //IP层

             IPPROTO_TCP  //TCp层

    @optname 

              选项

    @optval  选项对应的一些具体值

 

    @optlen  optval值的大小

 

 返回值:

   成功  0

   失败 -1 &errno

 

//接收超时的设置

   //1.设置超时时间

   struct timeval tm = {5,0};

 

if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tm,sizeof(tm)) < 0)

{

    perror("setsockopt fail");

    exit(EXIT_FAILURE);

}

 

 

//设置ip+port 复用--- 开启某些选项的功能

int on = 1; //大于0 的值表示开启这项功能

if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int)) < 0)

{

    perror("setsockopt fail");

    exit(EXIT_FAILURE);

}

 

Linux所提供的socket库中存在一个bug,即不能为一个套接字重新启用同一个端口,即使是你正常关闭该套接字以后,这是因为linux内核在一个绑定套接字的进程结束后从不把端口标记为未用。为了解决上述问题,setsockopt和getsockopt函数就被引进来了,当然它俩的功能不止这一点。

函数原型:

1.  int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

2.  int getsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

其中
    level
是函数所使用的协议标准,可以取如下值:

1.  SOL_SOCKET: 基本套接口

2.  IPPROTO_IP: IPv4套接口

3.  IPPROTO_IPV6: IPv6套接口

4.  IPPROTO_TCP: TCP套接口

    optval是指向setsockopt函数所设置的值的地址,getsockopt函数所获取的值
    optlen
是optval的长度,以bytes计
    optname
是选项的名称,可以取如下值:

1.  SO_BROADCAST BOOL类型 允许套接口传送广播信息

2.  SO_DEBUG BOOL类型记录调试信息

3.  SO_DONTLINER BOOL类型不要因为数据未发送就阻塞关闭操作

4.  SO_DONTROUTE BOOL类型禁止选择径;直接传送

5.  SO_KEEPALIVE BOOL类型发送保持活动包

6.  SO_LINGER struct linger FAR* 如关闭时有未发送数据,则逗留

7.  SO_OOBINLINE BOOL类型在常规数据流中接收带外(Out-Of-Band)数据

8.  SO_RCVBUF int类型为接收确定缓冲区大小

9.  SO_REUSEADDR BOOL类型允许套接口和一个已在使用中的地址捆绑

10. SO_SNDBUF int类型指定发送缓冲区大小

端口可重用的代码片断

1.  = socket(...)

2.  BOOL isReusable=TRUE;

3.  setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&isReusable,sizeof(BOOL));

 

//检测客户端是否存活

TCP:(内核协议栈实现的)

   keepalive

UDP:(心跳包的机制)

 客户端: 定时发送一个数据包  (alarm --- 信号 --- 信号处理函数(send,重启定时))

 服务器端:

         设置超时等待, 如果在指定的超时时间内,没有获得客户端的信息,则认为超时

 

注意:

   对于客户端的探测,我们通常放到应用层中去做

 

 

UDP 实现可靠传输:(相互的确认机制)

思路:

  每个包添加一个序号

  进行确认机制的添加

  c------S

   100-->

   <--101-

   ---102-> S

 

 

tcp:三次握手

    c  -----------   S

 

    -----SYN(j)------>

    <-ACK(j+1),SYN(K)--

    -----ACK(k+1)---->

 

-------------------------------------------------------

1.广播

单播

多播(组播)

广播

 

广播:

发送方--- 电台

1.创建套接字 socket() //SOCK_DGRAM

2.开启广播属性  setsockopt

3.填充广播地址信息 struct sockaddr_in

4.往广播地址中发消息 sendto

 

接收方:----- 收音机

1.创建套接字

2.填充广播地址

3.绑定广播地址 ---- 调频 bind

4.接收广播         recvfrom

 

  

多播:

  所用地址:

  D类地址

  224.0.0.1 ---- 239.255.255.255

 

   流程:

   发送方:

    [1].socket

    [2].填充多播地址

    [3].往多播地址中发送数据

   接收方:

    [1].socket

    [2].加入多播组

    [3].绑定多播地址 --- 类似调频

    [4].接收数据

 

struct ip_mreq

{

    struct in_addr imr_multiaddr; //指定的要加入的多播地址

    struct in_addr imr_interface; //指定从那张网卡接收数据

};

 

//1.定义多播请求的结构体变量进行填充

struct ip_mreqmreq;  

bzero(&mreq,sizeof(mreq));

 

mreq.imr_imr_multiaddr.s_addr= inet_addr(“224.10.10.1”);//填充多播地址

mreq.imr_imr_interface.s_addr= htonl(INADDR_ANY); //填充接收的网卡地址

//2.加入到多播组

setsockopt(sockfd,IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)); //加入多播组

//IPPROTO_IP  --- IP

//IP_ADD_MEMBERSHIP加入到多播组

1 0
原创粉丝点击