您的位置:首页 > 运维架构 > Linux

套接字设置

2018-04-02 16:55 393 查看
套接字设置      利用套接字能完成很多丰富得应用,但要想利用套接字实现更复杂得应用,必定会涉及到调整套接字属性,通过调整套接字属性,能够实现广播、组播、地址重用、数据缓冲区以及数据超时处理等功能。
 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_TCP:TCP协议层,用于设置TCP层
       参数optname\optval\optlen是3个相关得参数,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         生存时间                intIP_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_RCVBUF或SO_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_SNDBUF或SO_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、构造各种数据包(IP,ICMP,TCP,UDP),并进行发送
      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     协议
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scoket Linux Unix