• LINUX下getsockopt和setsockopt函数


    这两个函数仅用于套接字。

    函数原型:

    1 #include <sys/socket.h>
    2 #include <sys/types.h>
    3 
    4 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
    5 
    6 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

    sockfd:必须指向一个打开的套接字描述符

    level:指定系统中解释选项的代码或为通用套接字代码,或为某个特定于协议的代码(例如IPv4、IPv6、TCP或SCTP)。

    optval:指向某个变量(*optval)的指针,setsockopt从*optval中取得选项设置的新值,getsockopt则把以获取的选项当前值存入*optval。

    optlen:指定*optval的大小

    套接字选项的汇总可以查看unix网络编程(卷1)151页 图7-1和图7-2.

    并非所有实现都支持所有的套接字选项,下面的程序可以简单测试系统是否支持选项:

      1 /* include checkopts1 */
      2 /* *INDENT-OFF* */
      3 #include    "unp.h"
      4 #include    <netinet/tcp.h>        /* for TCP_xxx defines */
      5 
      6 union val {
      7   int                i_val;
      8   long                l_val;
      9   struct linger        linger_val;
     10   struct timeval    timeval_val;
     11 } val;
     12 
     13 static char    *sock_str_flag(union val *, int);
     14 static char    *sock_str_int(union val *, int);
     15 static char    *sock_str_linger(union val *, int);
     16 static char    *sock_str_timeval(union val *, int);
     17 
     18 struct sock_opts {
     19   const char       *opt_str;
     20   int        opt_level;
     21   int        opt_name;
     22   char   *(*opt_val_str)(union val *, int);
     23 } sock_opts[] = {
     24 #ifdef  SO_BROADCAST
     25     { "SO_BROADCAST",        SOL_SOCKET,    SO_BROADCAST,    sock_str_flag },
     26 #else
     27     { "SO_BROADCAST",            0,        0,        NULL},
     28 #endif
     29 #ifdef  SO_DEBUG
     30     { "SO_DEBUG",            SOL_SOCKET,    SO_DEBUG,        sock_str_flag },
     31 #else
     32     { "SO_DEBUG",                0,        0,        NULL},
     33 #endif
     34 #ifdef  SO_DONTROUTE
     35     { "SO_DONTROUTE",        SOL_SOCKET,    SO_DONTROUTE,    sock_str_flag },
     36 #else
     37     { "SO_DONTROUTE",            0,        0,        NULL},
     38 #endif
     39 #ifdef  SO_ERROR
     40     { "SO_ERROR",            SOL_SOCKET,    SO_ERROR,        sock_str_int },
     41 #else
     42     { "SO_ERROR",                0,        0,        NULL},
     43 #endif
     44 #ifdef  SO_KEEPALIVE
     45     { "SO_KEEPALIVE",        SOL_SOCKET,    SO_KEEPALIVE,    sock_str_flag },
     46 #else
     47     { "SO_KEEPALIVE",            0,        0,        NULL},
     48 #endif
     49 #ifdef  SO_LINGER
     50     { "SO_LINGER",            SOL_SOCKET,    SO_LINGER,        sock_str_linger },
     51 #else
     52     { "SO_LINGER",                0,        0,        NULL},
     53 #endif
     54 #ifdef  SO_OOBINLINE
     55     { "SO_OOBINLINE",        SOL_SOCKET,    SO_OOBINLINE,    sock_str_flag },
     56 #else
     57     : "SO_OOBINLINE",            0,        0,        NULL},
     58 #endif
     59 #ifdef  SO_RCVBUF
     60     { "SO_RCVBUF",            SOL_SOCKET,    SO_RCVBUF,        sock_str_int },
     61 #else
     62     { "SO_RCVBUF",                0,        0,        NULL},
     63 #endif
     64 #ifdef  SO_SNDBUF
     65     { "SO_SNDBUF",            SOL_SOCKET,    SO_SNDBUF,        sock_str_int },
     66 #else
     67     { "SO_SNDBUF",                0,        0,        NULL},
     68 #endif
     69 #ifdef  SO_RCVLOWAT
     70     { "SO_RCVLOWAT",        SOL_SOCKET,    SO_RCVLOWAT,    sock_str_int },
     71 #else
     72     { "SO_RCVLOWAT",            0,        0,        NULL},
     73 #endif
     74 #ifdef  SO_SNDLOWAT
     75     { "SO_SNDLOWAT",        SOL_SOCKET,    SO_SNDLOWAT,    sock_str_int },
     76 #else
     77     { "SO_SNDLOWAT",            0,        0,        NULL},
     78 #endif
     79 #ifdef  SO_RCVTIMEO
     80     { "SO_RCVTIMEO",        SOL_SOCKET,    SO_RCVTIMEO,    sock_str_timeval },
     81 #else
     82     { "SO_RCVTIMEO",            0,        0,        NULL},
     83 #endif
     84 #ifdef  SO_SNDTIMEO
     85     { "SO_SNDTIMEO",        SOL_SOCKET,    SO_SNDTIMEO,    sock_str_timeval },
     86 #else
     87     { "SO_SNDTIMEO",            0,        0,        NULL},
     88 #endif
     89 #ifdef  SO_REUSEADDR
     90     { "SO_REUSEADDR",        SOL_SOCKET,    SO_REUSEADDR,    sock_str_flag },
     91 #else
     92     { "SO_REUSEADDR",            0,        0,        NULL},
     93 #endif
     94 #ifdef    SO_REUSEPORT
     95     { "SO_REUSEPORT",        SOL_SOCKET,    SO_REUSEPORT,    sock_str_flag },
     96 #else
     97     { "SO_REUSEPORT",        0,            0,                NULL },
     98 #endif
     99 #ifdef  SO_TYPE
    100     { "SO_TYPE",            SOL_SOCKET,    SO_TYPE,        sock_str_int },
    101 #else
    102     { "SO_TYPE",            0,            0,        NULL},
    103 #endif
    104 #ifdef  SO_USELOOPBACK
    105     { "SO_USELOOPBACK",        SOL_SOCKET,    SO_USELOOPBACK,    sock_str_flag },
    106 #else
    107     { "SO_USELOOPBACK",        0,            0,                NULL},
    108 #endif
    109 #ifdef  IP_TOS
    110     { "IP_TOS",                IPPROTO_IP,    IP_TOS,            sock_str_int },
    111 #else
    112     { "IP_TOS",            0,            0,        NULL},
    113 #endif
    114 #ifdef  IP_TTL
    115     { "IP_TTL",                IPPROTO_IP,    IP_TTL,            sock_str_int },
    116 #else
    117     { "IP_TTL",            0,            0,        NULL},
    118 #endif
    119 #ifdef    IPV6_DONTFRAG
    120     { "IPV6_DONTFRAG",        IPPROTO_IPV6,IPV6_DONTFRAG,    sock_str_flag },
    121 #else
    122     { "IPV6_DONTFRAG",        0,            0,                NULL },
    123 #endif
    124 #ifdef    IPV6_UNICAST_HOPS
    125     { "IPV6_UNICAST_HOPS",    IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int },
    126 #else
    127     { "IPV6_UNICAST_HOPS",    0,            0,                NULL },
    128 #endif
    129 #ifdef    IPV6_V6ONLY
    130     { "IPV6_V6ONLY",        IPPROTO_IPV6,IPV6_V6ONLY,    sock_str_flag },
    131 #else
    132     { "IPV6_V6ONLY",        0,            0,                NULL },
    133 #endif
    134 #ifdef  TCP_MAXSEG
    135     { "TCP_MAXSEG",            IPPROTO_TCP,TCP_MAXSEG,        sock_str_int },
    136 #else
    137     { "TCP_MAXSEG",            0,            0,            NULL},
    138 #endif
    139 #ifdef  TCP_NODELAY
    140     { "TCP_NODELAY",        IPPROTO_TCP,TCP_NODELAY,    sock_str_flag },
    141 #else
    142     { "TCP_NODELAY",        0,            0,            NULL},
    143 #endif
    144 #ifdef    SCTP_AUTOCLOSE
    145     { "SCTP_AUTOCLOSE",        IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int },
    146 #else
    147     { "SCTP_AUTOCLOSE",        0,            0,                NULL },
    148 #endif
    149 #ifdef    SCTP_MAXBURST
    150     { "SCTP_MAXBURST",        IPPROTO_SCTP,SCTP_MAXBURST,    sock_str_int },
    151 #else
    152     { "SCTP_MAXBURST",        0,            0,                NULL },
    153 #endif
    154 #ifdef    SCTP_MAXSEG
    155     { "SCTP_MAXSEG",        IPPROTO_SCTP,SCTP_MAXSEG,    sock_str_int },
    156 #else
    157     { "SCTP_MAXSEG",        0,            0,                NULL },
    158 #endif
    159 #ifdef    SCTP_NODELAY
    160     { "SCTP_NODELAY",        IPPROTO_SCTP,SCTP_NODELAY,    sock_str_flag },
    161 #else
    162     { "SCTP_NODELAY",        0,            0,                NULL },
    163 #endif
    164     { NULL,                    0,            0,                NULL }
    165 };
    166 /* *INDENT-ON* */
    167 /* end checkopts1 */
    168 
    169 /* include checkopts2 */
    170 int
    171 main(int argc, char **argv)
    172 {
    173     int                    fd;
    174     socklen_t            len;
    175     struct sock_opts    *ptr;
    176 
    177     for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
    178         printf("%s: ", ptr->opt_str);
    179         if (ptr->opt_val_str == NULL)
    180             printf("(undefined)
    ");
    181         else {
    182             switch(ptr->opt_level) {
    183             case SOL_SOCKET:
    184             case IPPROTO_IP:
    185             case IPPROTO_TCP:
    186                 fd = Socket(AF_INET, SOCK_STREAM, 0);
    187                 break;
    188 #ifdef    IPV6
    189             case IPPROTO_IPV6:
    190                 fd = Socket(AF_INET6, SOCK_STREAM, 0);
    191                 break;
    192 #endif
    193 #ifdef    IPPROTO_SCTP
    194             case IPPROTO_SCTP:
    195                 fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
    196                 break;
    197 #endif
    198             default:
    199                 err_quit("Can't create fd for level %d
    ", ptr->opt_level);
    200             }
    201 
    202             len = sizeof(val);
    203             if (getsockopt(fd, ptr->opt_level, ptr->opt_name,
    204                            &val, &len) == -1) {
    205                 err_ret("getsockopt error");
    206             } else {
    207                 printf("default = %s
    ", (*ptr->opt_val_str)(&val, len));
    208             }
    209             close(fd);
    210         }
    211     }
    212     exit(0);
    213 }
    214 /* end checkopts2 */
    215 
    216 /* include checkopts3 */
    217 static char    strres[128];
    218 
    219 static char    *
    220 sock_str_flag(union val *ptr, int len)
    221 {
    222 /* *INDENT-OFF* */
    223     if (len != sizeof(int))
    224         snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
    225     else
    226         snprintf(strres, sizeof(strres),
    227                  "%s", (ptr->i_val == 0) ? "off" : "on");
    228     return(strres);
    229 /* *INDENT-ON* */
    230 }
    231 /* end checkopts3 */
    232 
    233 static char    *
    234 sock_str_int(union val *ptr, int len)
    235 {
    236     if (len != sizeof(int))
    237         snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
    238     else
    239         snprintf(strres, sizeof(strres), "%d", ptr->i_val);
    240     return(strres);
    241 }
    242 
    243 static char    *
    244 sock_str_linger(union val *ptr, int len)
    245 {
    246     struct linger    *lptr = &ptr->linger_val;
    247 
    248     if (len != sizeof(struct linger))
    249         snprintf(strres, sizeof(strres),
    250                  "size (%d) not sizeof(struct linger)", len);
    251     else
    252         snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",
    253                  lptr->l_onoff, lptr->l_linger);
    254     return(strres);
    255 }
    256 
    257 static char    *
    258 sock_str_timeval(union val *ptr, int len)
    259 {
    260     struct timeval    *tvptr = &ptr->timeval_val;
    261 
    262     if (len != sizeof(struct timeval))
    263         snprintf(strres, sizeof(strres),
    264                  "size (%d) not sizeof(struct timeval)", len);
    265     else
    266         snprintf(strres, sizeof(strres), "%ld sec, %ld usec",
    267                  tvptr->tv_sec, tvptr->tv_usec);
    268     return(strres);
    269 }

    我用的系统是Ubuntu 13.04,结果截图:

  • 相关阅读:
    参数传递(值传递与引用传递)
    存入redis中的java对象都需要序列化
    windows环境Apache服务器启动失败的原因
    IDEA/Eclipse安装 Alibaba Java Coding Guidelines 插件
    使用freemarker对模板进行渲染
    java使用freemarker作为模板导出Excel表格
    mybatis 中 foreach collection的三种用法
    利用freemarker导出页面格式复杂的excel
    mysql limit和offset用法
    设计模式之二十一:中介者模式(Mediator)
  • 原文地址:https://www.cnblogs.com/xianzhedeyu/p/3298649.html
Copyright © 2020-2023  润新知