套接字设置

套接字设置

      利用套接字能完成很多丰富得应用,但要想利用套接字实现更复杂得应用,必定会涉及到调整套接字属性,通过调整套接字属性,能够实现广播、组播、地址重用、数据缓冲区以及数据超时处理等功能。

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

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

参数sockfd----用于指定要操作的套接字

level ----- 用于指定套接字的操作层次,及当前要操作得协议层次

SOL_SOCKET :通用套接字层,用于设置通用套接字

IPPROTO_IP    IP协议层,用于设置IP

IPPROTO_TCPTCP协议层,用于设置TCP

       参数optname\optval\optlen3个相关得参数,optname对应选项名称,及针对那个选项设置,optval是选项所采用得数据结构,optlen是数据结构所占的字节数。以上3个参数的配置取决于level参数得设置。

选项名称        说明                  数据类型
========================================================================
SOL_SOCKET
------------------------------------------------------------------------
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
------------------------------------------------------------------------
IP_HDRINCL       在数据包中包含IP首部          int
IP_OPTINOSIP首部选项               int
IP_TOS服务类型
IP_TTL         生存时间                int

IP_ADD_MEMBERSHIP  组播                sizeof(ip_mreq)
========================================================================
IPPRO_TCP
------------------------------------------------------------------------
TCP_MAXSEGTCP最大数据段的大小           int
TCP_NODELAY       不使用Nagle算法             int
========================================================================

套接字设置应用:

    1、数据收发时限设置

    这项功能是设置数据包得接收与发送时限,以提升应用程序性能,即在规定的时间内,如果没有数据到来或数据包没有发送成功,则转入相应模块进行处理。

     Struct timeval timeout;

timeout . tv_sec = 5;

timeout . tv_usec = 0;

//接收时限

setsockopt( serversocket , SOL_SOCKET, SO_RECVTIMEO,(char *)&timeout, sizeof(timeoout));

//发送时限

setsockopt( serversocket , SOL_SOCKET, SO_SNDTIMEO,(char *)&timeout, sizeof(timeoout));

  2、修改数据收发缓存区  

      在接收与发送数据时,由于实际数据可能远远大于默认缓存区得大小,要想解决这个问题,除了可以循环调用接收与发送函数以外,还可以通过设置SO_RCVBUFSO_SNDBUF属性得方式完成。

//接收缓冲区

int opt = 1024 * 1024;

setsockopt( serversocket, SOL_SOCKET, SO_RCVBUF,(const char *) &opt, sizeof(opt));

//发送缓冲区

setsockopt( serversocket, SOL_SOCKET, SO_SNDBUF,(const char *) &opt, sizeof(opt));

 

3、广播设置

在发送数据包的时候,若希望该Socket发送得数据具有广播特性,则要进行下列得设置:

       int bBroadcast = 1;

setsockopt(serversocket, SOL_SOCKET, SO_BROADCAST, (const char *) &bBroadcast, sizeof(bBroadcast));

      4、直接数据复制

为提升系统性能,在发送或接收数据时,可以主动设置数据不经历由系统缓存区到套接字缓存区的拷贝,这个功能是由设置SO_SNDBUFSO_RECVBUF的参数值为0来实现的。

Int opt  = 0;

//设置发送

setsockopt( serversocket, SOL_SOCKET, SO_SNDBUF,(const char*) &opt, sizeof(opt));

  //设置接收

setsockopt( serversocket, SOL_SOCKET, SO_RECVBUF,(const char*) &opt, sizeof(opt));

 

 组播技术

       internet的某些应用中,有时候需要大量用户相互协作,若协作规模比较小,可以采用单播通信方式,直接点对点,单点对点得缺点是不管是信息的发送方还是接收方,都需要维护一个用户列表,代价比较高,有时候也可以采用广播通信方式,但如果是在拥有数十万个节点得网络中,使用广播会很低效,甚至不可能,因为此时大多数得主机对此信息可能不感兴趣。

因此需要一种折中得办法,既能实现小组范围内得互联,又能高校运转,为此,组播就应运而生。

 

224.0.0.1

      编程流程:

  1、套接字基本属性

   IP_ADD_MEMBERSHIP

   若要加入一个组播组,则要在setsockopt()中设置该选项,其中有一个重要的结构体:

struct ip_mreq

{

struct in_addr imr_multiaddr; //指定组播组的地址

struct in_addr imr_interface;  // 指定接口得IPV4地址

};

   IP_DROP_MEMBERSHIP

   用来从某个组播组中退出

   IP_MULTICAST_IF

   该选项可以修改网络接口,在结构体ip_mreq中定义新的接口

   IP_MULTICAST_TTL

   该选项用于设置组播报文的数据包的TTL(生存时间),默认值是1,表示数据包只能在本地的子网中传送。

   IP_MULTICAST_LOOP

    该选项表示组播组中的成员自已也会收到它向本组发送的报文。

2、组播工作流程

      服务器:

      struct sockaddr_in address;

memset(&address, 0 , sizeof(address));

address . sin_family = AF_INET;

address . sin_port = htons(8888);

address . sin_addr . s_addr = inet_addr(“224.0.0.1”);

 

       客户端:

    //在同一个主机上进行组播设置套接口

   bind(sockCli,(struct sockaddr*)&addrSer,sizeof(addrSer));

    struct ip_mreq multiaddress;

    multiaddress . imr_multiaddr.s_addr = inet_addr(“224.0.0.1”); in_addr

    multiaddress . imr_interface . s_addr = htonl(INADDR_ANY);

    //加入组播组

    if ( setsockopt ( client_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &multiaddress , sizeof (multiaddress))  < 0)

    {

printf(.......)

return 0;

}

   //结束时退出组播组

    if ( setsockopt ( client_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, &multiaddress , sizeof    (multiaddress))  < 0)

    {

printf(.......)

return 0;

}

socket(AF_INET,SOKC_STREAM\SOCK_DGRAM\SOCK_RAW)

原始套接字

     原始套接字是一种套接字底层技术,它工作在网络层,利用原始套接字可以完成以下功能:

      1、设置网卡为混杂模式,嗅探当前网络流经本网卡得所有数据包

      2、构造各种数据包(IPICMPTCPUDP),并进行发送

      3、进行新协议得验证

原始套接字的创建:

//创建可以获得所有IP层得数据报文的套接字

     int rawsock = socket(AF_INET, SOCK_RAW, htons(ETH_P_IP));

               协议码                               协议名

          IPPROTO_ICMP                   ICMP   协议

          ETH_P_IP                             IP         协议

          IPPROTO_TCP                     TCP      协议

          IPPROTO_UDP                     UDP     协议

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值